rustc: move function arguments into hir::Body.
This commit is contained in:
parent
e64f64a2fc
commit
f89856be6c
@ -51,6 +51,12 @@ impl DepGraph {
|
||||
}
|
||||
}
|
||||
|
||||
/// True if we are actually building the full dep-graph.
|
||||
#[inline]
|
||||
pub fn is_fully_enabled(&self) -> bool {
|
||||
self.data.thread.is_fully_enabled()
|
||||
}
|
||||
|
||||
pub fn query(&self) -> DepGraphQuery<DefId> {
|
||||
self.data.thread.query()
|
||||
}
|
||||
|
@ -395,6 +395,10 @@ pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_node_i
|
||||
}
|
||||
|
||||
pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
|
||||
for argument in &body.arguments {
|
||||
visitor.visit_id(argument.id);
|
||||
visitor.visit_pat(&argument.pat);
|
||||
}
|
||||
visitor.visit_expr(&body.value);
|
||||
}
|
||||
|
||||
@ -680,9 +684,12 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v
|
||||
visitor.visit_name(foreign_item.span, foreign_item.name);
|
||||
|
||||
match foreign_item.node {
|
||||
ForeignItemFn(ref function_declaration, ref generics) => {
|
||||
ForeignItemFn(ref function_declaration, ref names, ref generics) => {
|
||||
visitor.visit_generics(generics);
|
||||
visitor.visit_fn_decl(function_declaration);
|
||||
visitor.visit_generics(generics)
|
||||
for name in names {
|
||||
visitor.visit_name(name.span, name.node);
|
||||
}
|
||||
}
|
||||
ForeignItemStatic(ref typ, _) => visitor.visit_ty(typ),
|
||||
}
|
||||
@ -750,18 +757,8 @@ pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionR
|
||||
}
|
||||
|
||||
pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
|
||||
for argument in &function_declaration.inputs {
|
||||
visitor.visit_id(argument.id);
|
||||
visitor.visit_pat(&argument.pat);
|
||||
visitor.visit_ty(&argument.ty)
|
||||
}
|
||||
walk_fn_ret_ty(visitor, &function_declaration.output)
|
||||
}
|
||||
|
||||
pub fn walk_fn_decl_nopat<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
|
||||
for argument in &function_declaration.inputs {
|
||||
visitor.visit_id(argument.id);
|
||||
visitor.visit_ty(&argument.ty)
|
||||
for ty in &function_declaration.inputs {
|
||||
visitor.visit_ty(ty)
|
||||
}
|
||||
walk_fn_ret_ty(visitor, &function_declaration.output)
|
||||
}
|
||||
@ -799,12 +796,15 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
|
||||
visitor.visit_ty(ty);
|
||||
walk_list!(visitor, visit_nested_body, default);
|
||||
}
|
||||
TraitItemKind::Method(ref sig, None) => {
|
||||
TraitItemKind::Method(ref sig, TraitMethod::Required(ref names)) => {
|
||||
visitor.visit_id(trait_item.id);
|
||||
visitor.visit_generics(&sig.generics);
|
||||
visitor.visit_fn_decl(&sig.decl);
|
||||
for name in names {
|
||||
visitor.visit_name(name.span, name.node);
|
||||
}
|
||||
}
|
||||
TraitItemKind::Method(ref sig, Some(body_id)) => {
|
||||
TraitItemKind::Method(ref sig, TraitMethod::Provided(body_id)) => {
|
||||
visitor.visit_fn(FnKind::Method(trait_item.name,
|
||||
sig,
|
||||
None,
|
||||
@ -1113,16 +1113,3 @@ impl<'a, 'ast> Visitor<'ast> for IdRangeComputingVisitor<'a, 'ast> {
|
||||
self.result.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the id range for a single fn body, ignoring nested items.
|
||||
pub fn compute_id_range_for_fn_body<'v>(fk: FnKind<'v>,
|
||||
decl: &'v FnDecl,
|
||||
body: BodyId,
|
||||
sp: Span,
|
||||
id: NodeId,
|
||||
map: &map::Map<'v>)
|
||||
-> IdRange {
|
||||
let mut visitor = IdRangeComputingVisitor::new(map);
|
||||
visitor.visit_fn(fk, decl, body, sp, id);
|
||||
visitor.result()
|
||||
}
|
||||
|
@ -170,8 +170,12 @@ impl<'a> LoweringContext<'a> {
|
||||
visit::walk_crate(&mut item_lowerer, c);
|
||||
}
|
||||
|
||||
fn record_body(&mut self, value: hir::Expr) -> hir::BodyId {
|
||||
fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>)
|
||||
-> hir::BodyId {
|
||||
let body = hir::Body {
|
||||
arguments: decl.map_or(hir_vec![], |decl| {
|
||||
decl.inputs.iter().map(|x| self.lower_arg(x)).collect()
|
||||
}),
|
||||
value: value
|
||||
};
|
||||
let id = body.id();
|
||||
@ -310,11 +314,11 @@ impl<'a> LoweringContext<'a> {
|
||||
TyKind::Array(ref ty, ref length) => {
|
||||
let length = self.lower_expr(length);
|
||||
hir::TyArray(self.lower_ty(ty),
|
||||
self.record_body(length))
|
||||
self.record_body(length, None))
|
||||
}
|
||||
TyKind::Typeof(ref expr) => {
|
||||
let expr = self.lower_expr(expr);
|
||||
hir::TyTypeof(self.record_body(expr))
|
||||
hir::TyTypeof(self.record_body(expr, None))
|
||||
}
|
||||
TyKind::PolyTraitRef(ref bounds) => {
|
||||
hir::TyPolyTraitRef(self.lower_bounds(bounds))
|
||||
@ -343,7 +347,7 @@ impl<'a> LoweringContext<'a> {
|
||||
data: self.lower_variant_data(&v.node.data),
|
||||
disr_expr: v.node.disr_expr.as_ref().map(|e| {
|
||||
let e = self.lower_expr(e);
|
||||
self.record_body(e)
|
||||
self.record_body(e, None)
|
||||
}),
|
||||
},
|
||||
span: v.span,
|
||||
@ -532,13 +536,24 @@ impl<'a> LoweringContext<'a> {
|
||||
hir::Arg {
|
||||
id: arg.id,
|
||||
pat: self.lower_pat(&arg.pat),
|
||||
ty: self.lower_ty(&arg.ty),
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_fn_args_to_names(&mut self, decl: &FnDecl)
|
||||
-> hir::HirVec<Spanned<Name>> {
|
||||
decl.inputs.iter().map(|arg| {
|
||||
match arg.pat.node {
|
||||
PatKind::Ident(_, ident, None) => {
|
||||
respan(ident.span, ident.node.name)
|
||||
}
|
||||
_ => respan(arg.pat.span, keywords::Invalid.name()),
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn lower_fn_decl(&mut self, decl: &FnDecl) -> P<hir::FnDecl> {
|
||||
P(hir::FnDecl {
|
||||
inputs: decl.inputs.iter().map(|x| self.lower_arg(x)).collect(),
|
||||
inputs: decl.inputs.iter().map(|arg| self.lower_ty(&arg.ty)).collect(),
|
||||
output: match decl.output {
|
||||
FunctionRetTy::Ty(ref ty) => hir::Return(self.lower_ty(ty)),
|
||||
FunctionRetTy::Default(span) => hir::DefaultReturn(span),
|
||||
@ -869,17 +884,17 @@ impl<'a> LoweringContext<'a> {
|
||||
let value = self.lower_expr(e);
|
||||
hir::ItemStatic(self.lower_ty(t),
|
||||
self.lower_mutability(m),
|
||||
self.record_body(value))
|
||||
self.record_body(value, None))
|
||||
}
|
||||
ItemKind::Const(ref t, ref e) => {
|
||||
let value = self.lower_expr(e);
|
||||
hir::ItemConst(self.lower_ty(t),
|
||||
self.record_body(value))
|
||||
self.record_body(value, None))
|
||||
}
|
||||
ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
|
||||
let body = self.lower_block(body);
|
||||
let body = self.expr_block(body, ThinVec::new());
|
||||
let body_id = self.record_body(body);
|
||||
let body_id = self.record_body(body, Some(decl));
|
||||
hir::ItemFn(self.lower_fn_decl(decl),
|
||||
self.lower_unsafety(unsafety),
|
||||
self.lower_constness(constness),
|
||||
@ -948,16 +963,20 @@ impl<'a> LoweringContext<'a> {
|
||||
hir::TraitItemKind::Const(this.lower_ty(ty),
|
||||
default.as_ref().map(|x| {
|
||||
let value = this.lower_expr(x);
|
||||
this.record_body(value)
|
||||
this.record_body(value, None)
|
||||
}))
|
||||
}
|
||||
TraitItemKind::Method(ref sig, ref body) => {
|
||||
TraitItemKind::Method(ref sig, None) => {
|
||||
let names = this.lower_fn_args_to_names(&sig.decl);
|
||||
hir::TraitItemKind::Method(this.lower_method_sig(sig),
|
||||
body.as_ref().map(|x| {
|
||||
let body = this.lower_block(x);
|
||||
let expr = this.expr_block(body, ThinVec::new());
|
||||
this.record_body(expr)
|
||||
}))
|
||||
hir::TraitMethod::Required(names))
|
||||
}
|
||||
TraitItemKind::Method(ref sig, Some(ref body)) => {
|
||||
let body = this.lower_block(body);
|
||||
let expr = this.expr_block(body, ThinVec::new());
|
||||
let body_id = this.record_body(expr, Some(&sig.decl));
|
||||
hir::TraitItemKind::Method(this.lower_method_sig(sig),
|
||||
hir::TraitMethod::Provided(body_id))
|
||||
}
|
||||
TraitItemKind::Type(ref bounds, ref default) => {
|
||||
hir::TraitItemKind::Type(this.lower_bounds(bounds),
|
||||
@ -1005,13 +1024,13 @@ impl<'a> LoweringContext<'a> {
|
||||
node: match i.node {
|
||||
ImplItemKind::Const(ref ty, ref expr) => {
|
||||
let value = this.lower_expr(expr);
|
||||
let body_id = this.record_body(value);
|
||||
let body_id = this.record_body(value, None);
|
||||
hir::ImplItemKind::Const(this.lower_ty(ty), body_id)
|
||||
}
|
||||
ImplItemKind::Method(ref sig, ref body) => {
|
||||
let body = this.lower_block(body);
|
||||
let expr = this.expr_block(body, ThinVec::new());
|
||||
let body_id = this.record_body(expr);
|
||||
let body_id = this.record_body(expr, Some(&sig.decl));
|
||||
hir::ImplItemKind::Method(this.lower_method_sig(sig), body_id)
|
||||
}
|
||||
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
|
||||
@ -1097,7 +1116,9 @@ impl<'a> LoweringContext<'a> {
|
||||
attrs: this.lower_attrs(&i.attrs),
|
||||
node: match i.node {
|
||||
ForeignItemKind::Fn(ref fdec, ref generics) => {
|
||||
hir::ForeignItemFn(this.lower_fn_decl(fdec), this.lower_generics(generics))
|
||||
hir::ForeignItemFn(this.lower_fn_decl(fdec),
|
||||
this.lower_fn_args_to_names(fdec),
|
||||
this.lower_generics(generics))
|
||||
}
|
||||
ForeignItemKind::Static(ref t, m) => {
|
||||
hir::ForeignItemStatic(this.lower_ty(t), m)
|
||||
@ -1367,7 +1388,7 @@ impl<'a> LoweringContext<'a> {
|
||||
ExprKind::Repeat(ref expr, ref count) => {
|
||||
let expr = P(self.lower_expr(expr));
|
||||
let count = self.lower_expr(count);
|
||||
hir::ExprRepeat(expr, self.record_body(count))
|
||||
hir::ExprRepeat(expr, self.record_body(count, None))
|
||||
}
|
||||
ExprKind::Tup(ref elts) => {
|
||||
hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect())
|
||||
@ -1450,7 +1471,7 @@ impl<'a> LoweringContext<'a> {
|
||||
let expr = this.lower_expr(body);
|
||||
hir::ExprClosure(this.lower_capture_clause(capture_clause),
|
||||
this.lower_fn_decl(decl),
|
||||
this.record_body(expr),
|
||||
this.record_body(expr, Some(decl)),
|
||||
fn_decl_span)
|
||||
})
|
||||
}
|
||||
@ -1734,13 +1755,7 @@ impl<'a> LoweringContext<'a> {
|
||||
// `::std::option::Option::Some(<pat>) => <body>`
|
||||
let pat_arm = {
|
||||
let body_block = self.lower_block(body);
|
||||
let body_span = body_block.span;
|
||||
let body_expr = P(hir::Expr {
|
||||
id: self.next_id(),
|
||||
node: hir::ExprBlock(body_block),
|
||||
span: body_span,
|
||||
attrs: ThinVec::new(),
|
||||
});
|
||||
let body_expr = P(self.expr_block(body_block, ThinVec::new()));
|
||||
let pat = self.lower_pat(pat);
|
||||
let some_pat = self.pat_some(e.span, pat);
|
||||
|
||||
|
@ -62,7 +62,10 @@ impl MaybeFnLike for ast::Item {
|
||||
|
||||
impl MaybeFnLike for ast::TraitItem {
|
||||
fn is_fn_like(&self) -> bool {
|
||||
match self.node { ast::TraitItemKind::Method(_, Some(_)) => true, _ => false, }
|
||||
match self.node {
|
||||
ast::TraitItemKind::Method(_, ast::TraitMethod::Provided(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,7 +255,7 @@ impl<'a> FnLikeNode<'a> {
|
||||
_ => bug!("item FnLikeNode that is not fn-like"),
|
||||
},
|
||||
map::NodeTraitItem(ti) => match ti.node {
|
||||
ast::TraitItemKind::Method(ref sig, Some(body)) => {
|
||||
ast::TraitItemKind::Method(ref sig, ast::TraitMethod::Provided(body)) => {
|
||||
method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs)
|
||||
}
|
||||
_ => bug!("trait method FnLikeNode that is not fn-like"),
|
||||
|
@ -389,7 +389,9 @@ impl<'ast> Map<'ast> {
|
||||
fn is_trait_item_body(&self, node_id: NodeId, item: &TraitItem) -> bool {
|
||||
match item.node {
|
||||
TraitItemKind::Const(_, Some(body)) |
|
||||
TraitItemKind::Method(_, Some(body)) => body.node_id == node_id,
|
||||
TraitItemKind::Method(_, TraitMethod::Provided(body)) => {
|
||||
body.node_id == node_id
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -868,6 +868,7 @@ pub struct BodyId {
|
||||
/// The body of a function or constant value.
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct Body {
|
||||
pub arguments: HirVec<Arg>,
|
||||
pub value: Expr
|
||||
}
|
||||
|
||||
@ -1102,6 +1103,16 @@ pub struct TraitItem {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
/// A trait method's body (or just argument names).
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum TraitMethod {
|
||||
/// No default body in the trait, just a signature.
|
||||
Required(HirVec<Spanned<Name>>),
|
||||
|
||||
/// Both signature and body are provided in the trait.
|
||||
Provided(BodyId),
|
||||
}
|
||||
|
||||
/// Represents a trait method or associated constant or type
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum TraitItemKind {
|
||||
@ -1109,7 +1120,7 @@ pub enum TraitItemKind {
|
||||
/// must contain a value)
|
||||
Const(P<Ty>, Option<BodyId>),
|
||||
/// A method with an optional body
|
||||
Method(MethodSig, Option<BodyId>),
|
||||
Method(MethodSig, TraitMethod),
|
||||
/// An associated type with (possibly empty) bounds and optional concrete
|
||||
/// type
|
||||
Type(TyParamBounds, Option<P<Ty>>),
|
||||
@ -1248,7 +1259,6 @@ pub struct InlineAsm {
|
||||
/// represents an argument in a function header
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct Arg {
|
||||
pub ty: P<Ty>,
|
||||
pub pat: P<Pat>,
|
||||
pub id: NodeId,
|
||||
}
|
||||
@ -1256,7 +1266,7 @@ pub struct Arg {
|
||||
/// Represents the header (not the body) of a function declaration
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct FnDecl {
|
||||
pub inputs: HirVec<Arg>,
|
||||
pub inputs: HirVec<P<Ty>>,
|
||||
pub output: FunctionRetTy,
|
||||
pub variadic: bool,
|
||||
}
|
||||
@ -1639,7 +1649,7 @@ pub struct ForeignItem {
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum ForeignItem_ {
|
||||
/// A foreign function
|
||||
ForeignItemFn(P<FnDecl>, Generics),
|
||||
ForeignItemFn(P<FnDecl>, HirVec<Spanned<Name>>, Generics),
|
||||
/// A foreign static item (`static ext: u8`), with optional mutability
|
||||
/// (the boolean is true when mutable)
|
||||
ForeignItemStatic(P<Ty>, bool),
|
||||
|
@ -20,7 +20,6 @@ use syntax::print::pp::{Breaks, eof};
|
||||
use syntax::print::pp::Breaks::{Consistent, Inconsistent};
|
||||
use syntax::print::pprust::{self as ast_pp, PrintState};
|
||||
use syntax::ptr::P;
|
||||
use syntax::symbol::keywords;
|
||||
use syntax_pos::{self, BytePos};
|
||||
use errors;
|
||||
|
||||
@ -267,10 +266,6 @@ pub fn where_clause_to_string(i: &hir::WhereClause) -> String {
|
||||
to_string(|s| s.print_where_clause(i))
|
||||
}
|
||||
|
||||
pub fn fn_block_to_string(p: &hir::FnDecl) -> String {
|
||||
to_string(|s| s.print_fn_block_args(p))
|
||||
}
|
||||
|
||||
pub fn path_to_string(p: &hir::Path) -> String {
|
||||
to_string(|s| s.print_path(p, false))
|
||||
}
|
||||
@ -283,24 +278,35 @@ pub fn name_to_string(name: ast::Name) -> String {
|
||||
to_string(|s| s.print_name(name))
|
||||
}
|
||||
|
||||
pub fn fun_to_string(decl: &hir::FnDecl,
|
||||
unsafety: hir::Unsafety,
|
||||
constness: hir::Constness,
|
||||
name: ast::Name,
|
||||
generics: &hir::Generics)
|
||||
-> String {
|
||||
to_string(|s| {
|
||||
s.head("")?;
|
||||
s.print_fn(decl,
|
||||
unsafety,
|
||||
constness,
|
||||
Abi::Rust,
|
||||
Some(name),
|
||||
generics,
|
||||
&hir::Inherited)?;
|
||||
s.end()?; // Close the head box
|
||||
s.end() // Close the outer box
|
||||
})
|
||||
pub fn fn_decl_in_crate_to_string(krate: &hir::Crate,
|
||||
decl: &hir::FnDecl,
|
||||
unsafety: hir::Unsafety,
|
||||
constness: hir::Constness,
|
||||
name: ast::Name,
|
||||
generics: &hir::Generics,
|
||||
body_id: hir::BodyId)
|
||||
-> String {
|
||||
|
||||
let mut wr = Vec::new();
|
||||
{
|
||||
let mut s = rust_printer(Box::new(&mut wr), Some(krate));
|
||||
(|s: &mut State| {
|
||||
s.head("")?;
|
||||
s.print_fn(decl,
|
||||
unsafety,
|
||||
constness,
|
||||
Abi::Rust,
|
||||
Some(name),
|
||||
generics,
|
||||
&hir::Inherited,
|
||||
&[],
|
||||
Some(body_id))?;
|
||||
s.end()?; // Close the head box
|
||||
s.end()?; // Close the outer box
|
||||
eof(&mut s.s)
|
||||
})(&mut s).unwrap();
|
||||
}
|
||||
String::from_utf8(wr).unwrap()
|
||||
}
|
||||
|
||||
pub fn block_to_string(blk: &hir::Block) -> String {
|
||||
@ -317,10 +323,6 @@ pub fn variant_to_string(var: &hir::Variant) -> String {
|
||||
to_string(|s| s.print_variant(var))
|
||||
}
|
||||
|
||||
pub fn arg_to_string(arg: &hir::Arg) -> String {
|
||||
to_string(|s| s.print_arg(arg, false))
|
||||
}
|
||||
|
||||
pub fn visibility_qualified(vis: &hir::Visibility, s: &str) -> String {
|
||||
match *vis {
|
||||
hir::Public => format!("pub {}", s),
|
||||
@ -569,7 +571,7 @@ impl<'a> State<'a> {
|
||||
self.maybe_print_comment(item.span.lo)?;
|
||||
self.print_outer_attributes(&item.attrs)?;
|
||||
match item.node {
|
||||
hir::ForeignItemFn(ref decl, ref generics) => {
|
||||
hir::ForeignItemFn(ref decl, ref arg_names, ref generics) => {
|
||||
self.head("")?;
|
||||
self.print_fn(decl,
|
||||
hir::Unsafety::Normal,
|
||||
@ -577,7 +579,9 @@ impl<'a> State<'a> {
|
||||
Abi::Rust,
|
||||
Some(item.name),
|
||||
generics,
|
||||
&item.vis)?;
|
||||
&item.vis,
|
||||
arg_names,
|
||||
None)?;
|
||||
self.end()?; // end head-ibox
|
||||
word(&mut self.s, ";")?;
|
||||
self.end() // end the outer fn box
|
||||
@ -644,13 +648,14 @@ impl<'a> State<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_body(&mut self, body_id: hir::BodyId) -> Option<&'a hir::Body> {
|
||||
self.krate.map(|krate| krate.body(body_id))
|
||||
}
|
||||
|
||||
fn print_body_id(&mut self, body_id: hir::BodyId) -> io::Result<()> {
|
||||
if let Some(krate) = self.krate {
|
||||
let expr = &krate.body(body_id).value;
|
||||
self.print_expr(expr)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
self.maybe_body(body_id).map_or(Ok(()), |body| {
|
||||
self.print_expr(&body.value)
|
||||
})
|
||||
}
|
||||
|
||||
/// Pretty-print an item
|
||||
@ -734,7 +739,9 @@ impl<'a> State<'a> {
|
||||
abi,
|
||||
Some(item.name),
|
||||
typarams,
|
||||
&item.vis)?;
|
||||
&item.vis,
|
||||
&[],
|
||||
Some(body))?;
|
||||
word(&mut self.s, " ")?;
|
||||
self.end()?; // need to close a box
|
||||
self.end()?; // need to close a box
|
||||
@ -995,7 +1002,9 @@ impl<'a> State<'a> {
|
||||
pub fn print_method_sig(&mut self,
|
||||
name: ast::Name,
|
||||
m: &hir::MethodSig,
|
||||
vis: &hir::Visibility)
|
||||
vis: &hir::Visibility,
|
||||
arg_names: &[Spanned<ast::Name>],
|
||||
body_id: Option<hir::BodyId>)
|
||||
-> io::Result<()> {
|
||||
self.print_fn(&m.decl,
|
||||
m.unsafety,
|
||||
@ -1003,7 +1012,9 @@ impl<'a> State<'a> {
|
||||
m.abi,
|
||||
Some(name),
|
||||
&m.generics,
|
||||
vis)
|
||||
vis,
|
||||
arg_names,
|
||||
body_id)
|
||||
}
|
||||
|
||||
pub fn print_trait_item_ref(&mut self, item_ref: &hir::TraitItemRef) -> io::Result<()> {
|
||||
@ -1025,19 +1036,17 @@ impl<'a> State<'a> {
|
||||
hir::TraitItemKind::Const(ref ty, default) => {
|
||||
self.print_associated_const(ti.name, &ty, default, &hir::Inherited)?;
|
||||
}
|
||||
hir::TraitItemKind::Method(ref sig, body) => {
|
||||
if body.is_some() {
|
||||
self.head("")?;
|
||||
}
|
||||
self.print_method_sig(ti.name, sig, &hir::Inherited)?;
|
||||
if let Some(body) = body {
|
||||
self.nbsp()?;
|
||||
self.end()?; // need to close a box
|
||||
self.end()?; // need to close a box
|
||||
self.print_body_id(body)?;
|
||||
} else {
|
||||
word(&mut self.s, ";")?;
|
||||
}
|
||||
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref arg_names)) => {
|
||||
self.print_method_sig(ti.name, sig, &hir::Inherited, arg_names, None)?;
|
||||
word(&mut self.s, ";")?;
|
||||
}
|
||||
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
|
||||
self.head("")?;
|
||||
self.print_method_sig(ti.name, sig, &hir::Inherited, &[], Some(body))?;
|
||||
self.nbsp()?;
|
||||
self.end()?; // need to close a box
|
||||
self.end()?; // need to close a box
|
||||
self.print_body_id(body)?;
|
||||
}
|
||||
hir::TraitItemKind::Type(ref bounds, ref default) => {
|
||||
self.print_associated_type(ti.name,
|
||||
@ -1075,7 +1084,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
hir::ImplItemKind::Method(ref sig, body) => {
|
||||
self.head("")?;
|
||||
self.print_method_sig(ii.name, sig, &ii.vis)?;
|
||||
self.print_method_sig(ii.name, sig, &ii.vis, &[], Some(body))?;
|
||||
self.nbsp()?;
|
||||
self.end()?; // need to close a box
|
||||
self.end()?; // need to close a box
|
||||
@ -1442,7 +1451,7 @@ impl<'a> State<'a> {
|
||||
hir::ExprClosure(capture_clause, ref decl, body, _fn_decl_span) => {
|
||||
self.print_capture_clause(capture_clause)?;
|
||||
|
||||
self.print_fn_block_args(&decl)?;
|
||||
self.print_closure_args(&decl, body)?;
|
||||
space(&mut self.s)?;
|
||||
|
||||
// this is a bare expression
|
||||
@ -1966,7 +1975,9 @@ impl<'a> State<'a> {
|
||||
abi: Abi,
|
||||
name: Option<ast::Name>,
|
||||
generics: &hir::Generics,
|
||||
vis: &hir::Visibility)
|
||||
vis: &hir::Visibility,
|
||||
arg_names: &[Spanned<ast::Name>],
|
||||
body_id: Option<hir::BodyId>)
|
||||
-> io::Result<()> {
|
||||
self.print_fn_header_info(unsafety, constness, abi, vis)?;
|
||||
|
||||
@ -1975,24 +1986,58 @@ impl<'a> State<'a> {
|
||||
self.print_name(name)?;
|
||||
}
|
||||
self.print_generics(generics)?;
|
||||
self.print_fn_args_and_ret(decl)?;
|
||||
self.print_where_clause(&generics.where_clause)
|
||||
}
|
||||
|
||||
pub fn print_fn_args_and_ret(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
|
||||
self.popen()?;
|
||||
self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))?;
|
||||
let mut i = 0;
|
||||
// Make sure we aren't supplied *both* `arg_names` and `body_id`.
|
||||
assert!(arg_names.is_empty() || body_id.is_none());
|
||||
let args = body_id.and_then(|body_id| self.maybe_body(body_id))
|
||||
.map_or(&[][..], |body| &body.arguments[..]);
|
||||
self.commasep(Inconsistent, &decl.inputs, |s, ty| {
|
||||
s.ibox(indent_unit)?;
|
||||
if let Some(name) = arg_names.get(i) {
|
||||
word(&mut s.s, &name.node.as_str())?;
|
||||
word(&mut s.s, ":")?;
|
||||
space(&mut s.s)?;
|
||||
} else if let Some(arg) = args.get(i) {
|
||||
s.print_pat(&arg.pat)?;
|
||||
word(&mut s.s, ":")?;
|
||||
space(&mut s.s)?;
|
||||
}
|
||||
i += 1;
|
||||
s.print_type(ty)?;
|
||||
s.end()
|
||||
})?;
|
||||
if decl.variadic {
|
||||
word(&mut self.s, ", ...")?;
|
||||
}
|
||||
self.pclose()?;
|
||||
|
||||
self.print_fn_output(decl)
|
||||
self.print_fn_output(decl)?;
|
||||
self.print_where_clause(&generics.where_clause)
|
||||
}
|
||||
|
||||
pub fn print_fn_block_args(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
|
||||
fn print_closure_args(&mut self, decl: &hir::FnDecl, body_id: hir::BodyId) -> io::Result<()> {
|
||||
word(&mut self.s, "|")?;
|
||||
self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true))?;
|
||||
let mut i = 0;
|
||||
let args = self.maybe_body(body_id).map_or(&[][..], |body| &body.arguments[..]);
|
||||
self.commasep(Inconsistent, &decl.inputs, |s, ty| {
|
||||
s.ibox(indent_unit)?;
|
||||
|
||||
if let Some(arg) = args.get(i) {
|
||||
s.print_pat(&arg.pat)?;
|
||||
} else {
|
||||
word(&mut s.s, "_")?;
|
||||
}
|
||||
i += 1;
|
||||
|
||||
if ty.node != hir::TyInfer {
|
||||
word(&mut s.s, ":")?;
|
||||
space(&mut s.s)?;
|
||||
s.print_type(ty)?;
|
||||
}
|
||||
s.end()
|
||||
})?;
|
||||
word(&mut self.s, "|")?;
|
||||
|
||||
if let hir::DefaultReturn(..) = decl.output {
|
||||
@ -2164,27 +2209,6 @@ impl<'a> State<'a> {
|
||||
self.print_type(&mt.ty)
|
||||
}
|
||||
|
||||
pub fn print_arg(&mut self, input: &hir::Arg, is_closure: bool) -> io::Result<()> {
|
||||
self.ibox(indent_unit)?;
|
||||
match input.ty.node {
|
||||
hir::TyInfer if is_closure => self.print_pat(&input.pat)?,
|
||||
_ => {
|
||||
let invalid = if let PatKind::Binding(_, _, name, _) = input.pat.node {
|
||||
name.node == keywords::Invalid.name()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if !invalid {
|
||||
self.print_pat(&input.pat)?;
|
||||
word(&mut self.s, ":")?;
|
||||
space(&mut self.s)?;
|
||||
}
|
||||
self.print_type(&input.ty)?;
|
||||
}
|
||||
}
|
||||
self.end()
|
||||
}
|
||||
|
||||
pub fn print_fn_output(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
|
||||
if let hir::DefaultReturn(..) = decl.output {
|
||||
return Ok(());
|
||||
@ -2232,7 +2256,9 @@ impl<'a> State<'a> {
|
||||
abi,
|
||||
name,
|
||||
&generics,
|
||||
&hir::Inherited)?;
|
||||
&hir::Inherited,
|
||||
&[],
|
||||
None)?;
|
||||
self.end()
|
||||
}
|
||||
|
||||
|
@ -1051,8 +1051,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
Some(ref node) => match *node {
|
||||
ast_map::NodeItem(ref item) => {
|
||||
match item.node {
|
||||
hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => {
|
||||
Some((fn_decl, gen, unsafety, constness, item.name, item.span))
|
||||
hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, body) => {
|
||||
Some((fn_decl, gen, unsafety, constness, item.name, item.span, body))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
@ -1066,26 +1066,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if let hir::ImplItemKind::Method(ref sig, _) = item.node {
|
||||
if let hir::ImplItemKind::Method(ref sig, body) = item.node {
|
||||
Some((&sig.decl,
|
||||
&sig.generics,
|
||||
sig.unsafety,
|
||||
sig.constness,
|
||||
item.name,
|
||||
item.span))
|
||||
item.span,
|
||||
body))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
ast_map::NodeTraitItem(item) => {
|
||||
match item.node {
|
||||
hir::TraitItemKind::Method(ref sig, Some(_)) => {
|
||||
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
|
||||
Some((&sig.decl,
|
||||
&sig.generics,
|
||||
sig.unsafety,
|
||||
sig.constness,
|
||||
item.name,
|
||||
item.span))
|
||||
item.span,
|
||||
body))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
@ -1094,12 +1096,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
let (fn_decl, generics, unsafety, constness, name, span)
|
||||
let (fn_decl, generics, unsafety, constness, name, span, body)
|
||||
= node_inner.expect("expect item fn");
|
||||
let rebuilder = Rebuilder::new(self.tcx, fn_decl, generics, same_regions, &life_giver);
|
||||
let (fn_decl, generics) = rebuilder.rebuild();
|
||||
self.give_expl_lifetime_param(
|
||||
err, &fn_decl, unsafety, constness, name, &generics, span);
|
||||
err, &fn_decl, unsafety, constness, name, &generics, span, body);
|
||||
}
|
||||
|
||||
pub fn issue_32330_warnings(&self, span: Span, issue32330s: &[ty::Issue32330]) {
|
||||
@ -1375,23 +1377,14 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn rebuild_args_ty(&self,
|
||||
inputs: &[hir::Arg],
|
||||
inputs: &[P<hir::Ty>],
|
||||
lifetime: hir::Lifetime,
|
||||
anon_nums: &HashSet<u32>,
|
||||
region_names: &HashSet<ast::Name>)
|
||||
-> hir::HirVec<hir::Arg> {
|
||||
let mut new_inputs = Vec::new();
|
||||
for arg in inputs {
|
||||
let new_ty = self.rebuild_arg_ty_or_output(&arg.ty, lifetime,
|
||||
anon_nums, region_names);
|
||||
let possibly_new_arg = hir::Arg {
|
||||
ty: new_ty,
|
||||
pat: arg.pat.clone(),
|
||||
id: arg.id
|
||||
};
|
||||
new_inputs.push(possibly_new_arg);
|
||||
}
|
||||
new_inputs.into()
|
||||
-> hir::HirVec<P<hir::Ty>> {
|
||||
inputs.iter().map(|arg_ty| {
|
||||
self.rebuild_arg_ty_or_output(arg_ty, lifetime, anon_nums, region_names)
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn rebuild_output(&self, ty: &hir::FunctionRetTy,
|
||||
@ -1634,10 +1627,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
constness: hir::Constness,
|
||||
name: ast::Name,
|
||||
generics: &hir::Generics,
|
||||
span: Span) {
|
||||
let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, name, generics);
|
||||
let msg = format!("consider using an explicit lifetime \
|
||||
parameter as shown: {}", suggested_fn);
|
||||
span: Span,
|
||||
body: hir::BodyId) {
|
||||
let s = pprust::fn_decl_in_crate_to_string(self.tcx.map.krate(),
|
||||
decl,
|
||||
unsafety,
|
||||
constness,
|
||||
name,
|
||||
generics,
|
||||
body);
|
||||
let msg = format!("consider using an explicit lifetime parameter as shown: {}", s);
|
||||
err.span_help(span, &msg[..]);
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,6 @@ pub struct NativeLibrary {
|
||||
pub struct InlinedItem {
|
||||
pub def_id: DefId,
|
||||
pub body: hir::Body,
|
||||
pub const_fn_args: Vec<Option<DefId>>,
|
||||
}
|
||||
|
||||
/// A borrowed version of `hir::InlinedItem`. This is what's encoded when saving
|
||||
@ -149,14 +148,6 @@ pub struct InlinedItem {
|
||||
pub struct InlinedItemRef<'a> {
|
||||
pub def_id: DefId,
|
||||
pub body: &'a hir::Body,
|
||||
pub const_fn_args: Vec<Option<DefId>>,
|
||||
}
|
||||
|
||||
fn get_fn_args(decl: &hir::FnDecl) -> Vec<Option<DefId>> {
|
||||
decl.inputs.iter().map(|arg| match arg.pat.node {
|
||||
hir::PatKind::Binding(_, def_id, _, _) => Some(def_id),
|
||||
_ => None
|
||||
}).collect()
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InlinedItemRef<'tcx> {
|
||||
@ -164,16 +155,14 @@ impl<'a, 'tcx> InlinedItemRef<'tcx> {
|
||||
item: &hir::Item,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> InlinedItemRef<'tcx> {
|
||||
let (body_id, args) = match item.node {
|
||||
hir::ItemFn(ref decl, _, _, _, _, body_id) =>
|
||||
(body_id, get_fn_args(decl)),
|
||||
hir::ItemConst(_, body_id) => (body_id, vec![]),
|
||||
let body_id = match item.node {
|
||||
hir::ItemFn(.., body_id) |
|
||||
hir::ItemConst(_, body_id) => body_id,
|
||||
_ => bug!("InlinedItemRef::from_item wrong kind")
|
||||
};
|
||||
InlinedItemRef {
|
||||
def_id: def_id,
|
||||
body: tcx.map.body(body_id),
|
||||
const_fn_args: args
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,9 +170,8 @@ impl<'a, 'tcx> InlinedItemRef<'tcx> {
|
||||
item: &hir::TraitItem,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> InlinedItemRef<'tcx> {
|
||||
let (body_id, args) = match item.node {
|
||||
hir::TraitItemKind::Const(_, Some(body_id)) =>
|
||||
(body_id, vec![]),
|
||||
let body_id = match item.node {
|
||||
hir::TraitItemKind::Const(_, Some(body_id)) => body_id,
|
||||
hir::TraitItemKind::Const(_, None) => {
|
||||
bug!("InlinedItemRef::from_trait_item called for const without body")
|
||||
},
|
||||
@ -192,7 +180,6 @@ impl<'a, 'tcx> InlinedItemRef<'tcx> {
|
||||
InlinedItemRef {
|
||||
def_id: def_id,
|
||||
body: tcx.map.body(body_id),
|
||||
const_fn_args: args
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,17 +187,14 @@ impl<'a, 'tcx> InlinedItemRef<'tcx> {
|
||||
item: &hir::ImplItem,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> InlinedItemRef<'tcx> {
|
||||
let (body_id, args) = match item.node {
|
||||
hir::ImplItemKind::Method(ref sig, body_id) =>
|
||||
(body_id, get_fn_args(&sig.decl)),
|
||||
hir::ImplItemKind::Const(_, body_id) =>
|
||||
(body_id, vec![]),
|
||||
let body_id = match item.node {
|
||||
hir::ImplItemKind::Method(_, body_id) |
|
||||
hir::ImplItemKind::Const(_, body_id) => body_id,
|
||||
_ => bug!("InlinedItemRef::from_impl_item wrong kind")
|
||||
};
|
||||
InlinedItemRef {
|
||||
def_id: def_id,
|
||||
body: tcx.map.body(body_id),
|
||||
const_fn_args: args
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O
|
||||
}
|
||||
}
|
||||
|
||||
fn build_nodeid_to_index(decl: Option<&hir::FnDecl>,
|
||||
fn build_nodeid_to_index(body: Option<&hir::Body>,
|
||||
cfg: &cfg::CFG) -> NodeMap<Vec<CFGIndex>> {
|
||||
let mut index = NodeMap();
|
||||
|
||||
@ -168,8 +168,8 @@ fn build_nodeid_to_index(decl: Option<&hir::FnDecl>,
|
||||
// into cfg itself? i.e. introduce a fn-based flow-graph in
|
||||
// addition to the current block-based flow-graph, rather than
|
||||
// have to put traversals like this here?
|
||||
if let Some(decl) = decl {
|
||||
add_entries_from_fn_decl(&mut index, decl, cfg.entry);
|
||||
if let Some(body) = body {
|
||||
add_entries_from_fn_body(&mut index, body, cfg.entry);
|
||||
}
|
||||
|
||||
cfg.graph.each_node(|node_idx, node| {
|
||||
@ -181,18 +181,22 @@ fn build_nodeid_to_index(decl: Option<&hir::FnDecl>,
|
||||
|
||||
return index;
|
||||
|
||||
fn add_entries_from_fn_decl(index: &mut NodeMap<Vec<CFGIndex>>,
|
||||
decl: &hir::FnDecl,
|
||||
/// Add mappings from the ast nodes for the formal bindings to
|
||||
/// the entry-node in the graph.
|
||||
fn add_entries_from_fn_body(index: &mut NodeMap<Vec<CFGIndex>>,
|
||||
body: &hir::Body,
|
||||
entry: CFGIndex) {
|
||||
//! add mappings from the ast nodes for the formal bindings to
|
||||
//! the entry-node in the graph.
|
||||
use hir::intravisit::Visitor;
|
||||
|
||||
struct Formals<'a> {
|
||||
entry: CFGIndex,
|
||||
index: &'a mut NodeMap<Vec<CFGIndex>>,
|
||||
}
|
||||
let mut formals = Formals { entry: entry, index: index };
|
||||
intravisit::walk_fn_decl(&mut formals, decl);
|
||||
impl<'a, 'v> intravisit::Visitor<'v> for Formals<'a> {
|
||||
for arg in &body.arguments {
|
||||
formals.visit_pat(&arg.pat);
|
||||
}
|
||||
impl<'a, 'v> Visitor<'v> for Formals<'a> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v> {
|
||||
intravisit::NestedVisitorMap::None
|
||||
}
|
||||
@ -227,7 +231,7 @@ pub enum KillFrom {
|
||||
impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
analysis_name: &'static str,
|
||||
decl: Option<&hir::FnDecl>,
|
||||
body: Option<&hir::Body>,
|
||||
cfg: &cfg::CFG,
|
||||
oper: O,
|
||||
id_range: IdRange,
|
||||
@ -250,7 +254,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
||||
let kills2 = zeroes;
|
||||
let on_entry = vec![entry; num_nodes * words_per_id];
|
||||
|
||||
let nodeid_to_index = build_nodeid_to_index(decl, cfg);
|
||||
let nodeid_to_index = build_nodeid_to_index(body, cfg);
|
||||
|
||||
DataFlowContext {
|
||||
tcx: tcx,
|
||||
|
@ -333,7 +333,7 @@ impl<'v, 'k> ItemLikeVisitor<'v> for LifeSeeder<'k> {
|
||||
let trait_item = self.krate.trait_item(trait_item_ref.id);
|
||||
match trait_item.node {
|
||||
hir::TraitItemKind::Const(_, Some(_)) |
|
||||
hir::TraitItemKind::Method(_, Some(_)) => {
|
||||
hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => {
|
||||
if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
|
||||
self.worklist.push(trait_item.id);
|
||||
}
|
||||
@ -573,11 +573,11 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
|
||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
|
||||
match trait_item.node {
|
||||
hir::TraitItemKind::Const(_, Some(body_id)) |
|
||||
hir::TraitItemKind::Method(_, Some(body_id)) => {
|
||||
hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)) => {
|
||||
self.visit_nested_body(body_id)
|
||||
}
|
||||
hir::TraitItemKind::Const(_, None) |
|
||||
hir::TraitItemKind::Method(_, None) |
|
||||
hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) |
|
||||
hir::TraitItemKind::Type(..) => {}
|
||||
}
|
||||
}
|
||||
|
@ -287,20 +287,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_fn(&mut self,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Body) {
|
||||
self.walk_arg_patterns(decl, &body.value);
|
||||
self.consume_expr(&body.value);
|
||||
}
|
||||
|
||||
fn walk_arg_patterns(&mut self,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Expr) {
|
||||
for arg in &decl.inputs {
|
||||
pub fn walk_fn(&mut self, body: &hir::Body) {
|
||||
for arg in &body.arguments {
|
||||
let arg_ty = return_if_err!(self.mc.infcx.node_ty(arg.pat.id));
|
||||
|
||||
let fn_body_scope_r = self.tcx().node_scope_region(body.id);
|
||||
let fn_body_scope_r = self.tcx().node_scope_region(body.value.id);
|
||||
let arg_cmt = self.mc.cat_rvalue(
|
||||
arg.id,
|
||||
arg.pat.span,
|
||||
@ -309,6 +300,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
|
||||
self.walk_irrefutable_pat(arg_cmt, &arg.pat);
|
||||
}
|
||||
|
||||
self.consume_expr(&body.value);
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
@ -381,7 +381,9 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
|
||||
|
||||
debug!("creating fn_maps: {:?}", &fn_maps as *const IrMaps);
|
||||
|
||||
for arg in &decl.inputs {
|
||||
let body = ir.tcx.map.body(body_id);
|
||||
|
||||
for arg in &body.arguments {
|
||||
arg.pat.each_binding(|_bm, arg_id, _x, path1| {
|
||||
debug!("adding argument {}", arg_id);
|
||||
let name = path1.node;
|
||||
@ -404,8 +406,6 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
|
||||
clean_exit_var: fn_maps.add_variable(CleanExit)
|
||||
};
|
||||
|
||||
let body = ir.tcx.map.body(body_id);
|
||||
|
||||
// compute liveness
|
||||
let mut lsets = Liveness::new(&mut fn_maps, specials);
|
||||
let entry_ln = lsets.compute(&body.value);
|
||||
@ -413,7 +413,7 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
|
||||
// check for various error conditions
|
||||
lsets.visit_body(body);
|
||||
lsets.check_ret(id, sp, fk, entry_ln, body);
|
||||
lsets.warn_about_unused_args(decl, entry_ln);
|
||||
lsets.warn_about_unused_args(body, entry_ln);
|
||||
}
|
||||
|
||||
fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
|
||||
@ -1502,8 +1502,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn warn_about_unused_args(&self, decl: &hir::FnDecl, entry_ln: LiveNode) {
|
||||
for arg in &decl.inputs {
|
||||
fn warn_about_unused_args(&self, body: &hir::Body, entry_ln: LiveNode) {
|
||||
for arg in &body.arguments {
|
||||
arg.pat.each_binding(|_bm, p_id, sp, path1| {
|
||||
let var = self.variable(p_id, sp);
|
||||
// Ignore unused self.
|
||||
|
@ -167,7 +167,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||
Some(ast_map::NodeTraitItem(trait_method)) => {
|
||||
match trait_method.node {
|
||||
hir::TraitItemKind::Const(_, ref default) => default.is_some(),
|
||||
hir::TraitItemKind::Method(_, ref body) => body.is_some(),
|
||||
hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => true,
|
||||
hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) |
|
||||
hir::TraitItemKind::Type(..) => false,
|
||||
}
|
||||
}
|
||||
@ -275,11 +276,11 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||
ast_map::NodeTraitItem(trait_method) => {
|
||||
match trait_method.node {
|
||||
hir::TraitItemKind::Const(_, None) |
|
||||
hir::TraitItemKind::Method(_, None) => {
|
||||
hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) => {
|
||||
// Keep going, nothing to get exported
|
||||
}
|
||||
hir::TraitItemKind::Const(_, Some(body_id)) |
|
||||
hir::TraitItemKind::Method(_, Some(body_id)) => {
|
||||
hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)) => {
|
||||
self.visit_nested_body(body_id);
|
||||
}
|
||||
hir::TraitItemKind::Type(..) => {}
|
||||
|
@ -190,7 +190,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
// Items always introduce a new root scope
|
||||
self.with(RootScope, |_, this| {
|
||||
match item.node {
|
||||
hir::ForeignItemFn(ref decl, ref generics) => {
|
||||
hir::ForeignItemFn(ref decl, _, ref generics) => {
|
||||
this.visit_early_late(item.id, decl, generics, |this| {
|
||||
intravisit::walk_foreign_item(this, item);
|
||||
})
|
||||
@ -266,7 +266,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
// methods in an impl can reuse label names.
|
||||
let saved = replace(&mut self.labels_in_fn, vec![]);
|
||||
|
||||
if let hir::TraitItemKind::Method(ref sig, None) = trait_item.node {
|
||||
if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) =
|
||||
trait_item.node {
|
||||
self.visit_early_late(
|
||||
trait_item.id,
|
||||
&sig.decl, &sig.generics,
|
||||
@ -860,8 +861,8 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
|
||||
debug!("insert_late_bound_lifetimes(decl={:?}, generics={:?})", decl, generics);
|
||||
|
||||
let mut constrained_by_input = ConstrainedCollector { regions: FxHashSet() };
|
||||
for arg in &decl.inputs {
|
||||
constrained_by_input.visit_ty(&arg.ty);
|
||||
for arg_ty in &decl.inputs {
|
||||
constrained_by_input.visit_ty(arg_ty);
|
||||
}
|
||||
|
||||
let mut appears_in_output = AllCollector {
|
||||
|
@ -1225,7 +1225,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
||||
// Use call-site for extent (unless this is a
|
||||
// trait method with no default; then fallback
|
||||
// to the method id).
|
||||
let extent = if let Some(body_id) = *body {
|
||||
let extent = if let hir::TraitMethod::Provided(body_id) = *body {
|
||||
// default impl: use call_site extent as free_id_outlive bound.
|
||||
tcx.region_maps.call_site_extent(id, body_id.node_id)
|
||||
} else {
|
||||
|
@ -189,7 +189,6 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
move_data: &move_data::FlowedMoveData<'c, 'tcx>,
|
||||
all_loans: &[Loan<'tcx>],
|
||||
fn_id: ast::NodeId,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Body) {
|
||||
debug!("check_loans(body id={})", body.value.id);
|
||||
|
||||
@ -202,7 +201,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
all_loans: all_loans,
|
||||
param_env: &infcx.parameter_environment
|
||||
};
|
||||
euv::ExprUseVisitor::new(&mut clcx, &infcx).walk_fn(decl, body);
|
||||
euv::ExprUseVisitor::new(&mut clcx, &infcx).walk_fn(body);
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
|
@ -41,7 +41,6 @@ mod move_error;
|
||||
|
||||
pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
fn_id: NodeId,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Body)
|
||||
-> (Vec<Loan<'tcx>>,
|
||||
move_data::MoveData<'tcx>) {
|
||||
@ -55,7 +54,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
|
||||
let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id);
|
||||
let infcx = bccx.tcx.borrowck_fake_infer_ctxt(param_env);
|
||||
euv::ExprUseVisitor::new(&mut glcx, &infcx).walk_fn(decl, body);
|
||||
euv::ExprUseVisitor::new(&mut glcx, &infcx).walk_fn(body);
|
||||
|
||||
glcx.report_potential_errors();
|
||||
let GatherLoanCtxt { all_loans, move_data, .. } = glcx;
|
||||
|
@ -179,7 +179,7 @@ fn borrowck_fn<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
|
||||
let AnalysisData { all_loans,
|
||||
loans: loan_dfcx,
|
||||
move_data: flowed_moves } =
|
||||
build_borrowck_dataflow_data(this, fk, decl, &cfg, body, sp, id);
|
||||
build_borrowck_dataflow_data(this, &cfg, body, id);
|
||||
|
||||
move_data::fragments::instrument_move_fragments(&flowed_moves.move_data,
|
||||
this.tcx,
|
||||
@ -194,31 +194,31 @@ fn borrowck_fn<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
|
||||
&flowed_moves,
|
||||
&all_loans[..],
|
||||
id,
|
||||
decl,
|
||||
body);
|
||||
|
||||
intravisit::walk_fn(this, fk, decl, body_id, sp, id);
|
||||
}
|
||||
|
||||
fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
|
||||
fk: FnKind<'tcx>,
|
||||
decl: &'tcx hir::FnDecl,
|
||||
cfg: &cfg::CFG,
|
||||
body: &'tcx hir::Body,
|
||||
sp: Span,
|
||||
id: ast::NodeId)
|
||||
-> AnalysisData<'a, 'tcx>
|
||||
{
|
||||
// Check the body of fn items.
|
||||
let tcx = this.tcx;
|
||||
let id_range = intravisit::compute_id_range_for_fn_body(fk, decl, body.id(), sp, id, &tcx.map);
|
||||
let id_range = {
|
||||
let mut visitor = intravisit::IdRangeComputingVisitor::new(&tcx.map);
|
||||
visitor.visit_body(body);
|
||||
visitor.result()
|
||||
};
|
||||
let (all_loans, move_data) =
|
||||
gather_loans::gather_loans_in_fn(this, id, decl, body);
|
||||
gather_loans::gather_loans_in_fn(this, id, body);
|
||||
|
||||
let mut loan_dfcx =
|
||||
DataFlowContext::new(this.tcx,
|
||||
"borrowck",
|
||||
Some(decl),
|
||||
Some(body),
|
||||
cfg,
|
||||
LoanDataFlowOperator,
|
||||
id_range,
|
||||
@ -235,7 +235,6 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
|
||||
this.tcx,
|
||||
cfg,
|
||||
id_range,
|
||||
decl,
|
||||
body);
|
||||
|
||||
AnalysisData { all_loans: all_loans,
|
||||
@ -266,11 +265,8 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
|
||||
let body = tcx.map.body(fn_parts.body);
|
||||
|
||||
let dataflow_data = build_borrowck_dataflow_data(&mut bccx,
|
||||
fn_parts.kind,
|
||||
&fn_parts.decl,
|
||||
cfg,
|
||||
body,
|
||||
fn_parts.span,
|
||||
fn_parts.id);
|
||||
|
||||
(bccx, dataflow_data)
|
||||
@ -1121,22 +1117,21 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
if let Categorization::Deref(ref inner_cmt, ..) = err.cmt.cat {
|
||||
if let Categorization::Local(local_id) = inner_cmt.cat {
|
||||
let parent = self.tcx.map.get_parent_node(local_id);
|
||||
let opt_fn_decl = FnLikeNode::from_node(self.tcx.map.get(parent))
|
||||
.map(|fn_like| fn_like.decl());
|
||||
|
||||
if let Some(fn_decl) = opt_fn_decl {
|
||||
if let Some(ref arg) = fn_decl.inputs.iter()
|
||||
.find(|ref arg| arg.pat.id == local_id) {
|
||||
if let Some(fn_like) = FnLikeNode::from_node(self.tcx.map.get(parent)) {
|
||||
if let Some(i) = self.tcx.map.body(fn_like.body()).arguments.iter()
|
||||
.position(|arg| arg.pat.id == local_id) {
|
||||
let arg_ty = &fn_like.decl().inputs[i];
|
||||
if let hir::TyRptr(
|
||||
opt_lifetime,
|
||||
hir::MutTy{mutbl: hir::Mutability::MutImmutable, ref ty}) =
|
||||
arg.ty.node {
|
||||
arg_ty.node {
|
||||
if let Some(lifetime) = opt_lifetime {
|
||||
if let Ok(snippet) = self.tcx.sess.codemap()
|
||||
.span_to_snippet(ty.span) {
|
||||
if let Ok(lifetime_snippet) = self.tcx.sess.codemap()
|
||||
.span_to_snippet(lifetime.span) {
|
||||
db.span_label(arg.ty.span,
|
||||
db.span_label(arg_ty.span,
|
||||
&format!("use `&{} mut {}` \
|
||||
here to make mutable",
|
||||
lifetime_snippet,
|
||||
@ -1145,9 +1140,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
else if let Ok(snippet) = self.tcx.sess.codemap()
|
||||
.span_to_snippet(arg.ty.span) {
|
||||
.span_to_snippet(arg_ty.span) {
|
||||
if snippet.starts_with("&") {
|
||||
db.span_label(arg.ty.span,
|
||||
db.span_label(arg_ty.span,
|
||||
&format!("use `{}` here to make mutable",
|
||||
snippet.replace("&", "&mut ")));
|
||||
}
|
||||
|
@ -655,13 +655,12 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
cfg: &cfg::CFG,
|
||||
id_range: IdRange,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Body)
|
||||
-> FlowedMoveData<'a, 'tcx> {
|
||||
let mut dfcx_moves =
|
||||
DataFlowContext::new(tcx,
|
||||
"flowed_move_data_moves",
|
||||
Some(decl),
|
||||
Some(body),
|
||||
cfg,
|
||||
MoveDataFlowOperator,
|
||||
id_range,
|
||||
@ -669,7 +668,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
let mut dfcx_assign =
|
||||
DataFlowContext::new(tcx,
|
||||
"flowed_move_data_assigns",
|
||||
Some(decl),
|
||||
Some(body),
|
||||
cfg,
|
||||
AssignDataFlowOperator,
|
||||
id_range,
|
||||
|
@ -43,39 +43,17 @@ struct OuterVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, _expr: &'tcx hir::Expr) {
|
||||
return // const, static and N in [T; N] - shouldn't contain anything
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
|
||||
if let hir::TraitItemKind::Const(..) = item.node {
|
||||
return // nothing worth match checking in a constant
|
||||
} else {
|
||||
intravisit::walk_trait_item(self, item);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) {
|
||||
if let hir::ImplItemKind::Const(..) = item.node {
|
||||
return // nothing worth match checking in a constant
|
||||
} else {
|
||||
intravisit::walk_impl_item(self, item);
|
||||
}
|
||||
NestedVisitorMap::OnlyBodies(&self.tcx.map)
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
|
||||
b: hir::BodyId, s: Span, id: ast::NodeId) {
|
||||
if let FnKind::Closure(..) = fk {
|
||||
span_bug!(s, "check_match: closure outside of function")
|
||||
}
|
||||
intravisit::walk_fn(self, fk, fd, b, s, id);
|
||||
|
||||
MatchVisitor {
|
||||
tcx: self.tcx,
|
||||
param_env: &ty::ParameterEnvironment::for_item(self.tcx, id)
|
||||
}.visit_fn(fk, fd, b, s, id);
|
||||
}.visit_body(self.tcx.map.body(b));
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +74,7 @@ struct MatchVisitor<'a, 'tcx: 'a> {
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
|
||||
NestedVisitorMap::OnlyBodies(&self.tcx.map)
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
|
||||
@ -119,13 +97,12 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
|
||||
self.check_patterns(false, slice::ref_slice(&loc.pat));
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
|
||||
b: hir::BodyId, s: Span, n: ast::NodeId) {
|
||||
intravisit::walk_fn(self, fk, fd, b, s, n);
|
||||
fn visit_body(&mut self, body: &'tcx hir::Body) {
|
||||
intravisit::walk_body(self, body);
|
||||
|
||||
for input in &fd.inputs {
|
||||
self.check_irrefutable(&input.pat, true);
|
||||
self.check_patterns(false, slice::ref_slice(&input.pat));
|
||||
for arg in &body.arguments {
|
||||
self.check_irrefutable(&arg.pat, true);
|
||||
self.check_patterns(false, slice::ref_slice(&arg.pat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -870,18 +870,16 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
Struct(_) => signal!(e, UnimplementedConstVal("tuple struct constructors")),
|
||||
callee => signal!(e, CallOn(callee)),
|
||||
};
|
||||
let (arg_defs, body) = match lookup_const_fn_by_id(tcx, did) {
|
||||
Some(ConstFnNode::Inlined(ii)) => (ii.const_fn_args.clone(), &ii.body),
|
||||
Some(ConstFnNode::Local(fn_like)) =>
|
||||
(fn_like.decl().inputs.iter()
|
||||
.map(|arg| match arg.pat.node {
|
||||
hir::PatKind::Binding(_, def_id, _, _) => Some(def_id),
|
||||
_ => None
|
||||
}).collect(),
|
||||
tcx.map.body(fn_like.body())),
|
||||
let body = match lookup_const_fn_by_id(tcx, did) {
|
||||
Some(ConstFnNode::Inlined(ii)) => &ii.body,
|
||||
Some(ConstFnNode::Local(fn_like)) => tcx.map.body(fn_like.body()),
|
||||
None => signal!(e, NonConstPath),
|
||||
};
|
||||
let result = &body.value;
|
||||
|
||||
let arg_defs = body.arguments.iter().map(|arg| match arg.pat.node {
|
||||
hir::PatKind::Binding(_, def_id, _, _) => Some(def_id),
|
||||
_ => None
|
||||
}).collect::<Vec<_>>();
|
||||
assert_eq!(arg_defs.len(), args.len());
|
||||
|
||||
let mut call_args = DefIdMap();
|
||||
@ -899,7 +897,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
debug!("const call({:?})", call_args);
|
||||
eval_const_expr_partial(tcx, result, ty_hint, Some(&call_args))?
|
||||
eval_const_expr_partial(tcx, &body.value, ty_hint, Some(&call_args))?
|
||||
},
|
||||
hir::ExprLit(ref lit) => match lit_to_const(&lit.node, tcx, ety) {
|
||||
Ok(val) => val,
|
||||
|
@ -476,8 +476,10 @@ enum SawTraitOrImplItemComponent {
|
||||
fn saw_trait_item(ti: &TraitItemKind) -> SawTraitOrImplItemComponent {
|
||||
match *ti {
|
||||
TraitItemKind::Const(..) => SawTraitOrImplItemConst,
|
||||
TraitItemKind::Method(ref sig, ref body) =>
|
||||
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, body.is_some()),
|
||||
TraitItemKind::Method(ref sig, TraitMethod::Required(_)) =>
|
||||
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, false),
|
||||
TraitItemKind::Method(ref sig, TraitMethod::Provided(_)) =>
|
||||
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, true),
|
||||
TraitItemKind::Type(..) => SawTraitOrImplItemType
|
||||
}
|
||||
}
|
||||
|
@ -271,12 +271,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext, trait_item: &hir::TraitItem) {
|
||||
if let hir::TraitItemKind::Method(_, None) = trait_item.node {
|
||||
fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
|
||||
if let hir::TraitItemKind::Method(_, hir::TraitMethod::Required(ref names)) = item.node {
|
||||
self.check_snake_case(cx,
|
||||
"trait method",
|
||||
&trait_item.name.as_str(),
|
||||
Some(trait_item.span));
|
||||
&item.name.as_str(),
|
||||
Some(item.span));
|
||||
for name in names {
|
||||
self.check_snake_case(cx, "variable", &name.node.as_str(), Some(name.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,14 +291,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
|
||||
// Exclude parameter names from foreign functions
|
||||
let parent_node = cx.tcx.map.get_parent_node(p.id);
|
||||
if let hir::map::NodeForeignItem(item) = cx.tcx.map.get(parent_node) {
|
||||
if let hir::ForeignItemFn(..) = item.node {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if let &PatKind::Binding(_, _, ref path1, _) = &p.node {
|
||||
self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span));
|
||||
}
|
||||
|
@ -240,11 +240,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext, trait_item: &hir::TraitItem) {
|
||||
if let hir::TraitItemKind::Method(ref sig, None) = trait_item.node {
|
||||
fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
|
||||
if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) = item.node {
|
||||
if sig.unsafety == hir::Unsafety::Unsafe {
|
||||
cx.span_lint(UNSAFE_CODE,
|
||||
trait_item.span,
|
||||
item.span,
|
||||
"declaration of an `unsafe` method")
|
||||
}
|
||||
}
|
||||
|
@ -679,7 +679,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
let sig = self.cx.tcx.erase_late_bound_regions(&sig);
|
||||
|
||||
for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
|
||||
self.check_type_for_ffi_and_report_errors(input_hir.ty.span, input_ty);
|
||||
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty);
|
||||
}
|
||||
|
||||
if let hir::Return(ref ret_hir) = decl.output {
|
||||
@ -713,7 +713,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
|
||||
if nmod.abi != Abi::RustIntrinsic && nmod.abi != Abi::PlatformIntrinsic {
|
||||
for ni in &nmod.items {
|
||||
match ni.node {
|
||||
hir::ForeignItemFn(ref decl, _) => {
|
||||
hir::ForeignItemFn(ref decl, _, _) => {
|
||||
vis.check_foreign_fn(ni.id, decl);
|
||||
}
|
||||
hir::ForeignItemStatic(ref ty, _) => {
|
||||
|
@ -97,11 +97,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedMut {
|
||||
fn check_fn(&mut self,
|
||||
cx: &LateContext,
|
||||
_: FnKind,
|
||||
decl: &hir::FnDecl,
|
||||
_: &hir::Body,
|
||||
_: &hir::FnDecl,
|
||||
body: &hir::Body,
|
||||
_: Span,
|
||||
_: ast::NodeId) {
|
||||
for a in &decl.inputs {
|
||||
for a in &body.arguments {
|
||||
self.check_unused_mut_pat(cx, slice::ref_slice(&a.pat));
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +128,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
||||
|
||||
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>
|
||||
{
|
||||
self.dep_graph.read(DepNode::MetaData(did));
|
||||
// FIXME(#38501) We've skipped a `read` on the `HirBody` of
|
||||
// a `fn` when encoding, so the dep-tracking wouldn't work.
|
||||
// This is only used by rustdoc anyway, which shouldn't have
|
||||
// incremental recompilation ever enabled.
|
||||
assert!(!self.dep_graph.is_fully_enabled());
|
||||
self.get_crate_data(did.krate).get_fn_arg_names(did.index)
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ use std::io::Cursor;
|
||||
use std::rc::Rc;
|
||||
use std::u32;
|
||||
use syntax::ast::{self, CRATE_NODE_ID};
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax::attr;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos;
|
||||
@ -442,10 +443,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
let kind = match trait_item.kind {
|
||||
ty::AssociatedKind::Const => EntryKind::AssociatedConst(container),
|
||||
ty::AssociatedKind::Method => {
|
||||
let fn_data = if let hir::TraitItemKind::Method(ref sig, _) = ast_item.node {
|
||||
let fn_data = if let hir::TraitItemKind::Method(_, ref m) = ast_item.node {
|
||||
let arg_names = match *m {
|
||||
hir::TraitMethod::Required(ref names) => {
|
||||
self.encode_fn_arg_names(names)
|
||||
}
|
||||
hir::TraitMethod::Provided(body) => {
|
||||
self.encode_fn_arg_names_for_body(body)
|
||||
}
|
||||
};
|
||||
FnData {
|
||||
constness: hir::Constness::NotConst,
|
||||
arg_names: self.encode_fn_arg_names(&sig.decl),
|
||||
arg_names: arg_names
|
||||
}
|
||||
} else {
|
||||
bug!()
|
||||
@ -518,10 +527,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
let kind = match impl_item.kind {
|
||||
ty::AssociatedKind::Const => EntryKind::AssociatedConst(container),
|
||||
ty::AssociatedKind::Method => {
|
||||
let fn_data = if let hir::ImplItemKind::Method(ref sig, _) = ast_item.node {
|
||||
let fn_data = if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node {
|
||||
FnData {
|
||||
constness: sig.constness,
|
||||
arg_names: self.encode_fn_arg_names(&sig.decl),
|
||||
arg_names: self.encode_fn_arg_names_for_body(body),
|
||||
}
|
||||
} else {
|
||||
bug!()
|
||||
@ -574,16 +583,23 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_fn_arg_names(&mut self, decl: &hir::FnDecl) -> LazySeq<ast::Name> {
|
||||
self.lazy_seq(decl.inputs.iter().map(|arg| {
|
||||
if let PatKind::Binding(_, _, ref path1, _) = arg.pat.node {
|
||||
path1.node
|
||||
} else {
|
||||
Symbol::intern("")
|
||||
fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId)
|
||||
-> LazySeq<ast::Name> {
|
||||
let _ignore = self.tcx.dep_graph.in_ignore();
|
||||
let body = self.tcx.map.body(body_id);
|
||||
self.lazy_seq(body.arguments.iter().map(|arg| {
|
||||
match arg.pat.node {
|
||||
PatKind::Binding(_, _, name, _) => name.node,
|
||||
_ => Symbol::intern("")
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn encode_fn_arg_names(&mut self, names: &[Spanned<ast::Name>])
|
||||
-> LazySeq<ast::Name> {
|
||||
self.lazy_seq(names.iter().map(|name| name.node))
|
||||
}
|
||||
|
||||
fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> {
|
||||
self.tcx.mir_map.borrow().get(&def_id).map(|mir| self.lazy(&*mir.borrow()))
|
||||
}
|
||||
@ -619,10 +635,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
hir::ItemStatic(_, hir::MutMutable, _) => EntryKind::MutStatic,
|
||||
hir::ItemStatic(_, hir::MutImmutable, _) => EntryKind::ImmStatic,
|
||||
hir::ItemConst(..) => EntryKind::Const,
|
||||
hir::ItemFn(ref decl, _, constness, ..) => {
|
||||
hir::ItemFn(_, _, constness, .., body) => {
|
||||
let data = FnData {
|
||||
constness: constness,
|
||||
arg_names: self.encode_fn_arg_names(&decl),
|
||||
arg_names: self.encode_fn_arg_names_for_body(body),
|
||||
};
|
||||
|
||||
EntryKind::Fn(self.lazy(&data))
|
||||
@ -915,10 +931,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
debug!("writing foreign item {}", tcx.node_path_str(nitem.id));
|
||||
|
||||
let kind = match nitem.node {
|
||||
hir::ForeignItemFn(ref fndecl, _) => {
|
||||
hir::ForeignItemFn(_, ref names, _) => {
|
||||
let data = FnData {
|
||||
constness: hir::Constness::NotConst,
|
||||
arg_names: self.encode_fn_arg_names(&fndecl),
|
||||
arg_names: self.encode_fn_arg_names(names),
|
||||
};
|
||||
EntryKind::ForeignFn(self.lazy(&data))
|
||||
}
|
||||
|
@ -729,7 +729,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
name: Some(name),
|
||||
source_info: Some(source_info),
|
||||
});
|
||||
let extent = self.extent_of_innermost_scope();
|
||||
let extent = self.hir.tcx().region_maps.var_scope(var_id);
|
||||
self.schedule_drop(source_info.span, extent, &Lvalue::Local(var), var_ty);
|
||||
self.var_indices.insert(var_id, var);
|
||||
|
||||
|
@ -126,7 +126,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
||||
arguments: A,
|
||||
abi: Abi,
|
||||
return_ty: Ty<'gcx>,
|
||||
body_id: hir::BodyId)
|
||||
body: &'gcx hir::Body)
|
||||
-> Mir<'tcx>
|
||||
where A: Iterator<Item=(Ty<'gcx>, Option<&'gcx hir::Pat>)>
|
||||
{
|
||||
@ -138,15 +138,14 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
let call_site_extent =
|
||||
tcx.region_maps.lookup_code_extent(
|
||||
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id.node_id });
|
||||
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body.value.id });
|
||||
let arg_extent =
|
||||
tcx.region_maps.lookup_code_extent(
|
||||
CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body_id.node_id });
|
||||
CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.value.id });
|
||||
let mut block = START_BLOCK;
|
||||
unpack!(block = builder.in_scope(call_site_extent, block, |builder| {
|
||||
unpack!(block = builder.in_scope(arg_extent, block, |builder| {
|
||||
let ast_expr = &tcx.map.body(body_id).value;
|
||||
builder.args_and_body(block, &arguments, arg_extent, ast_expr)
|
||||
builder.args_and_body(block, &arguments, arg_extent, &body.value)
|
||||
}));
|
||||
// Attribute epilogue to function's closing brace
|
||||
let fn_end = Span { lo: span.hi, ..span };
|
||||
|
@ -253,7 +253,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
f: F)
|
||||
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>)
|
||||
{
|
||||
let extent = self.extent_of_innermost_scope();
|
||||
let extent = self.scopes.last().map(|scope| scope.extent).unwrap();
|
||||
let loop_scope = LoopScope {
|
||||
extent: extent.clone(),
|
||||
continue_block: loop_block,
|
||||
@ -411,10 +411,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extent_of_innermost_scope(&self) -> CodeExtent {
|
||||
self.scopes.last().map(|scope| scope.extent).unwrap()
|
||||
}
|
||||
|
||||
/// Returns the extent of the scope which should be exited by a
|
||||
/// return.
|
||||
pub fn extent_of_return_scope(&self) -> CodeExtent {
|
||||
|
@ -234,8 +234,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
(self.tcx.item_type(def_id).fn_abi(), None)
|
||||
};
|
||||
|
||||
let body = self.tcx.map.body(body_id);
|
||||
let explicit_arguments =
|
||||
decl.inputs
|
||||
body.arguments
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, arg)| {
|
||||
@ -244,7 +245,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> {
|
||||
|
||||
let arguments = implicit_argument.into_iter().chain(explicit_arguments);
|
||||
self.cx(MirSource::Fn(id)).build(|cx| {
|
||||
build::construct_fn(cx, id, arguments, abi, fn_sig.output(), body_id)
|
||||
build::construct_fn(cx, id, arguments, abi, fn_sig.output(), body)
|
||||
});
|
||||
|
||||
intravisit::walk_fn(self, fk, decl, body_id, span, id);
|
||||
|
@ -166,7 +166,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
|
||||
|
||||
let qualif = self.with_mode(mode, |this| {
|
||||
let body = this.tcx.map.body(b);
|
||||
this.with_euv(Some(fn_id), |euv| euv.walk_fn(fd, body));
|
||||
this.with_euv(Some(fn_id), |euv| euv.walk_fn(body));
|
||||
intravisit::walk_fn(this, fk, fd, b, s, fn_id);
|
||||
this.qualif
|
||||
});
|
||||
|
@ -52,7 +52,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RvalueContext<'a, 'tcx> {
|
||||
};
|
||||
let body = infcx.tcx.map.body(b);
|
||||
let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx);
|
||||
euv.walk_fn(fd, body);
|
||||
euv.walk_fn(body);
|
||||
});
|
||||
intravisit::walk_fn(self, fk, fd, b, s, fn_id)
|
||||
}
|
||||
|
@ -227,6 +227,7 @@ pub fn ast_region_to_region<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
fn report_elision_failure(
|
||||
tcx: TyCtxt,
|
||||
db: &mut DiagnosticBuilder,
|
||||
params: Vec<ElisionFailureInfo>)
|
||||
{
|
||||
@ -241,13 +242,14 @@ fn report_elision_failure(
|
||||
|
||||
for (i, info) in elided_params.into_iter().enumerate() {
|
||||
let ElisionFailureInfo {
|
||||
name, lifetime_count: n, have_bound_regions
|
||||
parent, index, lifetime_count: n, have_bound_regions
|
||||
} = info;
|
||||
|
||||
let help_name = if name.is_empty() {
|
||||
format!("argument {}", i + 1)
|
||||
let help_name = if let Some(body) = parent {
|
||||
let arg = &tcx.map.body(body).arguments[index];
|
||||
format!("`{}`", pprust::pat_to_string(&arg.pat))
|
||||
} else {
|
||||
format!("`{}`", name)
|
||||
format!("argument {}", index + 1)
|
||||
};
|
||||
|
||||
m.push_str(&(if n == 1 {
|
||||
@ -315,7 +317,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
err.span_label(ampersand_span, &format!("expected lifetime parameter"));
|
||||
|
||||
if let Some(params) = params {
|
||||
report_elision_failure(&mut err, params);
|
||||
report_elision_failure(self.tcx(), &mut err, params);
|
||||
}
|
||||
err.emit();
|
||||
ty::ReStatic
|
||||
@ -540,15 +542,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
/// corresponding to each input type/pattern.
|
||||
fn find_implied_output_region<I>(&self,
|
||||
input_tys: &[Ty<'tcx>],
|
||||
input_pats: I) -> ElidedLifetime
|
||||
where I: Iterator<Item=String>
|
||||
parent: Option<hir::BodyId>,
|
||||
input_indices: I) -> ElidedLifetime
|
||||
where I: Iterator<Item=usize>
|
||||
{
|
||||
let tcx = self.tcx();
|
||||
let mut lifetimes_for_params = Vec::with_capacity(input_tys.len());
|
||||
let mut possible_implied_output_region = None;
|
||||
let mut lifetimes = 0;
|
||||
|
||||
for input_type in input_tys.iter() {
|
||||
for (input_type, index) in input_tys.iter().zip(input_indices) {
|
||||
let mut regions = FxHashSet();
|
||||
let have_bound_regions = tcx.collect_regions(input_type, &mut regions);
|
||||
|
||||
@ -564,11 +567,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
possible_implied_output_region = regions.iter().cloned().next();
|
||||
}
|
||||
|
||||
// Use a placeholder for `name` because computing it can be
|
||||
// expensive and we don't want to do it until we know it's
|
||||
// necessary.
|
||||
lifetimes_for_params.push(ElisionFailureInfo {
|
||||
name: String::new(),
|
||||
parent: parent,
|
||||
index: index,
|
||||
lifetime_count: regions.len(),
|
||||
have_bound_regions: have_bound_regions
|
||||
});
|
||||
@ -577,11 +578,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
if lifetimes == 1 {
|
||||
Ok(*possible_implied_output_region.unwrap())
|
||||
} else {
|
||||
// Fill in the expensive `name` fields now that we know they're
|
||||
// needed.
|
||||
for (info, input_pat) in lifetimes_for_params.iter_mut().zip(input_pats) {
|
||||
info.name = input_pat;
|
||||
}
|
||||
Err(Some(lifetimes_for_params))
|
||||
}
|
||||
}
|
||||
@ -618,8 +614,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
let inputs = self.tcx().mk_type_list(data.inputs.iter().map(|a_t| {
|
||||
self.ast_ty_arg_to_ty(&binding_rscope, None, region_substs, a_t)
|
||||
}));
|
||||
let input_params = iter::repeat(String::new()).take(inputs.len());
|
||||
let implied_output_region = self.find_implied_output_region(&inputs, input_params);
|
||||
let input_params = 0..inputs.len();
|
||||
let implied_output_region = self.find_implied_output_region(&inputs, None, input_params);
|
||||
|
||||
let (output, output_span) = match data.output {
|
||||
Some(ref output_ty) => {
|
||||
@ -1572,6 +1568,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
bf.abi,
|
||||
None,
|
||||
&bf.decl,
|
||||
None,
|
||||
anon_scope,
|
||||
anon_scope);
|
||||
|
||||
@ -1696,26 +1693,28 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
|
||||
pub fn ty_of_arg(&self,
|
||||
rscope: &RegionScope,
|
||||
a: &hir::Arg,
|
||||
ty: &hir::Ty,
|
||||
expected_ty: Option<Ty<'tcx>>)
|
||||
-> Ty<'tcx>
|
||||
{
|
||||
match a.ty.node {
|
||||
match ty.node {
|
||||
hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
|
||||
hir::TyInfer => self.ty_infer(a.ty.span),
|
||||
_ => self.ast_ty_to_ty(rscope, &a.ty),
|
||||
hir::TyInfer => self.ty_infer(ty.span),
|
||||
_ => self.ast_ty_to_ty(rscope, ty),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ty_of_method(&self,
|
||||
sig: &hir::MethodSig,
|
||||
opt_self_value_ty: Option<Ty<'tcx>>,
|
||||
body: Option<hir::BodyId>,
|
||||
anon_scope: Option<AnonTypeScope>)
|
||||
-> &'tcx ty::BareFnTy<'tcx> {
|
||||
self.ty_of_method_or_bare_fn(sig.unsafety,
|
||||
sig.abi,
|
||||
opt_self_value_ty,
|
||||
&sig.decl,
|
||||
body,
|
||||
None,
|
||||
anon_scope)
|
||||
}
|
||||
@ -1724,9 +1723,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
unsafety: hir::Unsafety,
|
||||
abi: abi::Abi,
|
||||
decl: &hir::FnDecl,
|
||||
body: hir::BodyId,
|
||||
anon_scope: Option<AnonTypeScope>)
|
||||
-> &'tcx ty::BareFnTy<'tcx> {
|
||||
self.ty_of_method_or_bare_fn(unsafety, abi, None, decl, None, anon_scope)
|
||||
self.ty_of_method_or_bare_fn(unsafety, abi, None, decl, Some(body), None, anon_scope)
|
||||
}
|
||||
|
||||
fn ty_of_method_or_bare_fn(&self,
|
||||
@ -1734,6 +1734,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
abi: abi::Abi,
|
||||
opt_self_value_ty: Option<Ty<'tcx>>,
|
||||
decl: &hir::FnDecl,
|
||||
body: Option<hir::BodyId>,
|
||||
arg_anon_scope: Option<AnonTypeScope>,
|
||||
ret_anon_scope: Option<AnonTypeScope>)
|
||||
-> &'tcx ty::BareFnTy<'tcx>
|
||||
@ -1764,12 +1765,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
// reference) in the arguments, then any anonymous regions in the output
|
||||
// have that lifetime.
|
||||
_ => {
|
||||
let arg_params = &decl.inputs[has_self as usize..];
|
||||
let arg_tys = &input_tys[has_self as usize..];
|
||||
|
||||
self.find_implied_output_region(arg_tys,
|
||||
arg_params.iter()
|
||||
.map(|a| pprust::pat_to_string(&a.pat)))
|
||||
let arg_params = has_self as usize..input_tys.len();
|
||||
self.find_implied_output_region(arg_tys, body, arg_params)
|
||||
|
||||
}
|
||||
};
|
||||
|
@ -456,7 +456,7 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
|
||||
};
|
||||
|
||||
impl_m_iter.zip(trait_m_iter).find(|&(ref impl_arg, ref trait_arg)| {
|
||||
match (&impl_arg.ty.node, &trait_arg.ty.node) {
|
||||
match (&impl_arg.node, &trait_arg.node) {
|
||||
(&hir::TyRptr(_, ref impl_mt), &hir::TyRptr(_, ref trait_mt)) |
|
||||
(&hir::TyPtr(ref impl_mt), &hir::TyPtr(ref trait_mt)) => {
|
||||
impl_mt.mutbl != trait_mt.mutbl
|
||||
@ -464,7 +464,7 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
|
||||
_ => false,
|
||||
}
|
||||
}).map(|(ref impl_arg, ref trait_arg)| {
|
||||
(impl_arg.ty.span, Some(trait_arg.ty.span))
|
||||
(impl_arg.span, Some(trait_arg.span))
|
||||
})
|
||||
.unwrap_or_else(|| (cause.span, tcx.map.span_if_local(trait_m.def_id)))
|
||||
} else {
|
||||
@ -489,7 +489,7 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
|
||||
.filter_map(|(((impl_arg_ty, trait_arg_ty), impl_arg), trait_arg)| {
|
||||
match infcx.sub_types(true, &cause, trait_arg_ty, impl_arg_ty) {
|
||||
Ok(_) => None,
|
||||
Err(_) => Some((impl_arg.ty.span, Some(trait_arg.ty.span))),
|
||||
Err(_) => Some((impl_arg.span, Some(trait_arg.span))),
|
||||
}
|
||||
})
|
||||
.next()
|
||||
@ -680,7 +680,7 @@ fn compare_number_of_method_arguments<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
} else {
|
||||
0
|
||||
}) {
|
||||
Some(arg.pat.span)
|
||||
Some(arg.span)
|
||||
} else {
|
||||
trait_item_span
|
||||
}
|
||||
@ -698,7 +698,7 @@ fn compare_number_of_method_arguments<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
} else {
|
||||
0
|
||||
}) {
|
||||
arg.pat.span
|
||||
arg.span
|
||||
} else {
|
||||
impl_m_span
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
let i_n_tps = tcx.item_generics(def_id).types.len();
|
||||
if i_n_tps != n_tps {
|
||||
let span = match it.node {
|
||||
hir::ForeignItemFn(_, ref generics) => generics.span,
|
||||
hir::ForeignItemFn(_, _, ref generics) => generics.span,
|
||||
hir::ForeignItemStatic(..) => it.span
|
||||
};
|
||||
|
||||
|
@ -681,8 +681,8 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
fcx.check_casts();
|
||||
fcx.select_all_obligations_or_error(); // Casts can introduce new obligations.
|
||||
|
||||
fcx.regionck_fn(fn_id, decl, body);
|
||||
fcx.resolve_type_vars_in_fn(decl, body, fn_id);
|
||||
fcx.regionck_fn(fn_id, body);
|
||||
fcx.resolve_type_vars_in_body(body, fn_id);
|
||||
});
|
||||
}
|
||||
|
||||
@ -751,16 +751,6 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
|
||||
intravisit::walk_pat(self, p);
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: &'gcx hir::Ty) {
|
||||
match t.node {
|
||||
hir::TyBareFn(ref function_declaration) => {
|
||||
intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
|
||||
walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
|
||||
}
|
||||
_ => intravisit::walk_ty(self, t)
|
||||
}
|
||||
}
|
||||
|
||||
// Don't descend into the bodies of nested closures
|
||||
fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
|
||||
_: hir::BodyId, _: Span, _: ast::NodeId) { }
|
||||
@ -796,31 +786,21 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
||||
fn_sig = fcx.tcx.mk_fn_sig(fn_sig.inputs().iter().cloned(), &fcx.ret_ty.unwrap(),
|
||||
fn_sig.variadic);
|
||||
|
||||
{
|
||||
let mut visit = GatherLocalsVisitor { fcx: &fcx, };
|
||||
GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
|
||||
|
||||
// Add formal parameters.
|
||||
for (arg_ty, input) in fn_sig.inputs().iter().zip(&decl.inputs) {
|
||||
// The type of the argument must be well-formed.
|
||||
//
|
||||
// NB -- this is now checked in wfcheck, but that
|
||||
// currently only results in warnings, so we issue an
|
||||
// old-style WF obligation here so that we still get the
|
||||
// errors that we used to get.
|
||||
fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation);
|
||||
// Add formal parameters.
|
||||
for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
|
||||
// The type of the argument must be well-formed.
|
||||
//
|
||||
// NB -- this is now checked in wfcheck, but that
|
||||
// currently only results in warnings, so we issue an
|
||||
// old-style WF obligation here so that we still get the
|
||||
// errors that we used to get.
|
||||
fcx.register_old_wf_obligation(arg_ty, arg.pat.span, traits::MiscObligation);
|
||||
|
||||
// Create type variables for each argument.
|
||||
input.pat.each_binding(|_bm, pat_id, sp, _path| {
|
||||
let var_ty = visit.assign(sp, pat_id, None);
|
||||
fcx.require_type_is_sized(var_ty, sp, traits::VariableType(pat_id));
|
||||
});
|
||||
|
||||
// Check the pattern.
|
||||
fcx.check_pat(&input.pat, arg_ty);
|
||||
fcx.write_ty(input.id, arg_ty);
|
||||
}
|
||||
|
||||
visit.visit_body(body);
|
||||
// Check the pattern.
|
||||
fcx.check_pat(&arg.pat, arg_ty);
|
||||
fcx.write_ty(arg.id, arg_ty);
|
||||
}
|
||||
|
||||
inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
|
||||
@ -910,7 +890,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
||||
err.emit();
|
||||
}
|
||||
|
||||
if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
|
||||
if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node {
|
||||
require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span);
|
||||
}
|
||||
}
|
||||
@ -954,10 +934,10 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
||||
hir::TraitItemKind::Const(_, Some(expr)) => {
|
||||
check_const(ccx, expr, trait_item.id)
|
||||
}
|
||||
hir::TraitItemKind::Method(ref sig, Some(body_id)) => {
|
||||
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body_id)) => {
|
||||
check_bare_fn(ccx, &sig.decl, body_id, trait_item.id, trait_item.span);
|
||||
}
|
||||
hir::TraitItemKind::Method(_, None) |
|
||||
hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) |
|
||||
hir::TraitItemKind::Const(_, None) |
|
||||
hir::TraitItemKind::Type(..) => {
|
||||
// Nothing to do.
|
||||
@ -1269,7 +1249,7 @@ fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
|
||||
fcx.select_all_obligations_or_error();
|
||||
|
||||
fcx.regionck_expr(body);
|
||||
fcx.resolve_type_vars_in_expr(body, id);
|
||||
fcx.resolve_type_vars_in_body(body, id);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
pub fn regionck_fn(&self,
|
||||
fn_id: ast::NodeId,
|
||||
decl: &hir::FnDecl,
|
||||
body: &'gcx hir::Body) {
|
||||
debug!("regionck_fn(id={})", fn_id);
|
||||
let node_id = body.value.id;
|
||||
@ -149,7 +148,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
if self.err_count_since_creation() == 0 {
|
||||
// regionck assumes typeck succeeded
|
||||
rcx.visit_fn_body(fn_id, decl, body, self.tcx.map.span(fn_id));
|
||||
rcx.visit_fn_body(fn_id, body, self.tcx.map.span(fn_id));
|
||||
}
|
||||
|
||||
rcx.free_region_map.relate_free_regions_from_predicates(
|
||||
@ -268,7 +267,6 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
fn visit_fn_body(&mut self,
|
||||
id: ast::NodeId, // the id of the fn itself
|
||||
fn_decl: &hir::FnDecl,
|
||||
body: &'gcx hir::Body,
|
||||
span: Span)
|
||||
{
|
||||
@ -303,8 +301,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
let old_body_id = self.set_body_id(body_id.node_id);
|
||||
self.relate_free_regions(&fn_sig_tys[..], body_id.node_id, span);
|
||||
self.link_fn_args(self.tcx.region_maps.node_extent(body_id.node_id),
|
||||
&fn_decl.inputs[..]);
|
||||
self.link_fn_args(self.tcx.region_maps.node_extent(body_id.node_id), &body.arguments);
|
||||
self.visit_body(body);
|
||||
self.visit_region_obligations(body_id.node_id);
|
||||
|
||||
@ -483,10 +480,10 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, _fk: intravisit::FnKind<'gcx>, fd: &'gcx hir::FnDecl,
|
||||
fn visit_fn(&mut self, _fk: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
|
||||
b: hir::BodyId, span: Span, id: ast::NodeId) {
|
||||
let body = self.tcx.map.body(b);
|
||||
self.visit_fn_body(id, fd, body, span)
|
||||
self.visit_fn_body(id, body, span)
|
||||
}
|
||||
|
||||
//visit_pat: visit_pat, // (..) see above
|
||||
@ -1116,7 +1113,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
for arg in args {
|
||||
let arg_ty = self.node_ty(arg.id);
|
||||
let re_scope = self.tcx.mk_region(ty::ReScope(body_scope));
|
||||
let arg_cmt = mc.cat_rvalue(arg.id, arg.ty.span, re_scope, arg_ty);
|
||||
let arg_cmt = mc.cat_rvalue(arg.id, arg.pat.span, re_scope, arg_ty);
|
||||
debug!("arg_ty={:?} arg_cmt={:?} arg={:?}",
|
||||
arg_ty,
|
||||
arg_cmt,
|
||||
|
@ -157,7 +157,6 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
|
||||
fn analyze_closure(&mut self,
|
||||
id: ast::NodeId,
|
||||
span: Span,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Body) {
|
||||
/*!
|
||||
* Analysis starting point.
|
||||
@ -172,7 +171,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
|
||||
mc::MemCategorizationOptions {
|
||||
during_closure_kind_inference: true
|
||||
});
|
||||
euv.walk_fn(decl, body);
|
||||
euv.walk_fn(body);
|
||||
}
|
||||
|
||||
// Now that we've analyzed the closure, we know how each
|
||||
@ -505,7 +504,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for AdjustBorrowKind<'a, 'gcx, 'tcx> {
|
||||
|
||||
let body = self.fcx.tcx.map.body(body);
|
||||
self.visit_body(body);
|
||||
self.analyze_closure(id, span, decl, body);
|
||||
self.analyze_closure(id, span, body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -478,7 +478,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
let span = method_sig.decl.inputs[0].pat.span;
|
||||
let span = method_sig.decl.inputs[0].span;
|
||||
|
||||
let free_substs = &fcx.parameter_environment.free_substs;
|
||||
let method_ty = fcx.tcx.item_type(method.def_id);
|
||||
|
@ -28,40 +28,21 @@ use syntax_pos::Span;
|
||||
|
||||
use rustc::hir::print::pat_to_string;
|
||||
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
use rustc::hir::{self, PatKind};
|
||||
use rustc::hir;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Entry point functions
|
||||
// Entry point
|
||||
|
||||
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn resolve_type_vars_in_expr(&self, body: &'gcx hir::Body, item_id: ast::NodeId) {
|
||||
pub fn resolve_type_vars_in_body(&self,
|
||||
body: &'gcx hir::Body,
|
||||
item_id: ast::NodeId) {
|
||||
assert_eq!(self.writeback_errors.get(), false);
|
||||
let mut wbcx = WritebackCx::new(self);
|
||||
wbcx.visit_body(body);
|
||||
wbcx.visit_upvar_borrow_map();
|
||||
wbcx.visit_closures();
|
||||
wbcx.visit_liberated_fn_sigs();
|
||||
wbcx.visit_fru_field_types();
|
||||
wbcx.visit_deferred_obligations(item_id);
|
||||
wbcx.visit_type_nodes();
|
||||
}
|
||||
|
||||
pub fn resolve_type_vars_in_fn(&self,
|
||||
decl: &'gcx hir::FnDecl,
|
||||
body: &'gcx hir::Body,
|
||||
item_id: ast::NodeId) {
|
||||
assert_eq!(self.writeback_errors.get(), false);
|
||||
let mut wbcx = WritebackCx::new(self);
|
||||
wbcx.visit_body(body);
|
||||
for arg in &decl.inputs {
|
||||
for arg in &body.arguments {
|
||||
wbcx.visit_node_id(ResolvingPattern(arg.pat.span), arg.id);
|
||||
wbcx.visit_pat(&arg.pat);
|
||||
|
||||
// Privacy needs the type for the whole pattern, not just each binding
|
||||
if let PatKind::Binding(..) = arg.pat.node {} else {
|
||||
wbcx.visit_node_id(ResolvingPattern(arg.pat.span), arg.pat.id);
|
||||
}
|
||||
}
|
||||
wbcx.visit_body(body);
|
||||
wbcx.visit_upvar_borrow_map();
|
||||
wbcx.visit_closures();
|
||||
wbcx.visit_liberated_fn_sigs();
|
||||
@ -211,12 +192,12 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
self.visit_method_map_entry(ResolvingExpr(e.span),
|
||||
MethodCall::expr(e.id));
|
||||
|
||||
if let hir::ExprClosure(_, ref decl, body, _) = e.node {
|
||||
for input in &decl.inputs {
|
||||
self.visit_node_id(ResolvingExpr(e.span), input.id);
|
||||
if let hir::ExprClosure(_, _, body, _) = e.node {
|
||||
let body = self.fcx.tcx.map.body(body);
|
||||
for arg in &body.arguments {
|
||||
self.visit_node_id(ResolvingExpr(e.span), arg.id);
|
||||
}
|
||||
|
||||
let body = self.fcx.tcx.map.body(body);
|
||||
self.visit_body(body);
|
||||
}
|
||||
|
||||
@ -257,16 +238,6 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
self.write_ty_to_tcx(l.id, var_ty);
|
||||
intravisit::walk_local(self, l);
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: &'gcx hir::Ty) {
|
||||
match t.node {
|
||||
hir::TyBareFn(ref function_declaration) => {
|
||||
intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
|
||||
walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes);
|
||||
}
|
||||
_ => intravisit::walk_ty(self, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
|
@ -640,7 +640,8 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
id: ast::NodeId,
|
||||
sig: &hir::MethodSig,
|
||||
untransformed_rcvr_ty: Ty<'tcx>,
|
||||
rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
|
||||
body: Option<hir::BodyId>,
|
||||
rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,) {
|
||||
let def_id = ccx.tcx.map.local_def_id(id);
|
||||
let ty_generics = generics_of_def_id(ccx, def_id);
|
||||
|
||||
@ -658,7 +659,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
None
|
||||
};
|
||||
let fty = AstConv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
|
||||
sig, self_value_ty, anon_scope);
|
||||
sig, self_value_ty, body, anon_scope);
|
||||
|
||||
let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
|
||||
ccx.tcx.map.span(id), def_id);
|
||||
@ -865,10 +866,14 @@ fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) {
|
||||
convert_associated_type(ccx, TraitContainer(trait_def_id), trait_item.id, typ);
|
||||
}
|
||||
|
||||
hir::TraitItemKind::Method(ref sig, _) => {
|
||||
hir::TraitItemKind::Method(ref sig, ref method) => {
|
||||
let body = match *method {
|
||||
hir::TraitMethod::Required(_) => None,
|
||||
hir::TraitMethod::Provided(body) => Some(body)
|
||||
};
|
||||
convert_method(ccx, TraitContainer(trait_def_id),
|
||||
trait_item.id, sig, tcx.mk_self_type(),
|
||||
&trait_predicates);
|
||||
body, &trait_predicates);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -908,10 +913,10 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) {
|
||||
convert_associated_type(ccx, ImplContainer(impl_def_id), impl_item.id, Some(typ));
|
||||
}
|
||||
|
||||
hir::ImplItemKind::Method(ref sig, _) => {
|
||||
hir::ImplItemKind::Method(ref sig, body) => {
|
||||
convert_method(ccx, ImplContainer(impl_def_id),
|
||||
impl_item.id, sig, impl_self_ty,
|
||||
&impl_predicates);
|
||||
Some(body), &impl_predicates);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1429,7 +1434,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
NodeForeignItem(item) => {
|
||||
match item.node {
|
||||
ForeignItemStatic(..) => &no_generics,
|
||||
ForeignItemFn(_, ref generics) => generics
|
||||
ForeignItemFn(_, _, ref generics) => generics
|
||||
}
|
||||
}
|
||||
|
||||
@ -1530,9 +1535,9 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
ItemStatic(ref t, ..) | ItemConst(ref t, _) => {
|
||||
ccx.icx(&()).to_ty(&StaticRscope::new(&ccx.tcx), &t)
|
||||
}
|
||||
ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
|
||||
ItemFn(ref decl, unsafety, _, abi, ref generics, body) => {
|
||||
let tofd = AstConv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &decl,
|
||||
Some(AnonTypeScope::new(def_id)));
|
||||
body, Some(AnonTypeScope::new(def_id)));
|
||||
let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
|
||||
ccx.tcx.mk_fn_def(def_id, substs, tofd)
|
||||
}
|
||||
@ -1572,7 +1577,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
let abi = ccx.tcx.map.get_foreign_abi(node_id);
|
||||
|
||||
match foreign_item.node {
|
||||
ForeignItemFn(ref fn_decl, ref generics) => {
|
||||
ForeignItemFn(ref fn_decl, _, ref generics) => {
|
||||
compute_type_of_foreign_fn_decl(
|
||||
ccx, ccx.tcx.map.local_def_id(foreign_item.id),
|
||||
fn_decl, generics, abi)
|
||||
@ -1637,7 +1642,7 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
let no_generics = hir::Generics::empty();
|
||||
let generics = match it.node {
|
||||
hir::ForeignItemFn(_, ref generics) => generics,
|
||||
hir::ForeignItemFn(_, _, ref generics) => generics,
|
||||
hir::ForeignItemStatic(..) => &no_generics
|
||||
};
|
||||
|
||||
@ -2073,7 +2078,7 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
|
||||
}
|
||||
};
|
||||
for (input, ty) in decl.inputs.iter().zip(&input_tys) {
|
||||
check(&input.ty, ty)
|
||||
check(&input, ty)
|
||||
}
|
||||
if let hir::Return(ref ty) = decl.output {
|
||||
check(&ty, output)
|
||||
|
@ -8,6 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty;
|
||||
use rustc::ty::subst::Substs;
|
||||
@ -19,7 +20,10 @@ use syntax_pos::Span;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ElisionFailureInfo {
|
||||
pub name: String,
|
||||
/// Where we can find the argument pattern.
|
||||
pub parent: Option<hir::BodyId>,
|
||||
/// The index of the argument in the original definition.
|
||||
pub index: usize,
|
||||
pub lifetime_count: usize,
|
||||
pub have_bound_regions: bool
|
||||
}
|
||||
|
@ -1030,22 +1030,14 @@ pub struct Method {
|
||||
pub abi: Abi,
|
||||
}
|
||||
|
||||
impl Clean<Method> for hir::MethodSig {
|
||||
impl<'a> Clean<Method> for (&'a hir::MethodSig, hir::BodyId) {
|
||||
fn clean(&self, cx: &DocContext) -> Method {
|
||||
let decl = FnDecl {
|
||||
inputs: Arguments {
|
||||
values: self.decl.inputs.clean(cx),
|
||||
},
|
||||
output: self.decl.output.clean(cx),
|
||||
variadic: false,
|
||||
attrs: Attributes::default()
|
||||
};
|
||||
Method {
|
||||
generics: self.generics.clean(cx),
|
||||
unsafety: self.unsafety,
|
||||
constness: self.constness,
|
||||
decl: decl,
|
||||
abi: self.abi
|
||||
generics: self.0.generics.clean(cx),
|
||||
unsafety: self.0.unsafety,
|
||||
constness: self.0.constness,
|
||||
decl: (&*self.0.decl, self.1).clean(cx),
|
||||
abi: self.0.abi
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1058,25 +1050,6 @@ pub struct TyMethod {
|
||||
pub abi: Abi,
|
||||
}
|
||||
|
||||
impl Clean<TyMethod> for hir::MethodSig {
|
||||
fn clean(&self, cx: &DocContext) -> TyMethod {
|
||||
let decl = FnDecl {
|
||||
inputs: Arguments {
|
||||
values: self.decl.inputs.clean(cx),
|
||||
},
|
||||
output: self.decl.output.clean(cx),
|
||||
variadic: false,
|
||||
attrs: Attributes::default()
|
||||
};
|
||||
TyMethod {
|
||||
unsafety: self.unsafety.clone(),
|
||||
decl: decl,
|
||||
generics: self.generics.clean(cx),
|
||||
abi: self.abi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Function {
|
||||
pub decl: FnDecl,
|
||||
@ -1097,7 +1070,7 @@ impl Clean<Item> for doctree::Function {
|
||||
deprecation: self.depr.clean(cx),
|
||||
def_id: cx.tcx.map.local_def_id(self.id),
|
||||
inner: FunctionItem(Function {
|
||||
decl: self.decl.clean(cx),
|
||||
decl: (&self.decl, self.body).clean(cx),
|
||||
generics: self.generics.clean(cx),
|
||||
unsafety: self.unsafety,
|
||||
constness: self.constness,
|
||||
@ -1130,14 +1103,47 @@ pub struct Arguments {
|
||||
pub values: Vec<Argument>,
|
||||
}
|
||||
|
||||
impl Clean<FnDecl> for hir::FnDecl {
|
||||
impl<'a> Clean<Arguments> for (&'a [P<hir::Ty>], &'a [Spanned<ast::Name>]) {
|
||||
fn clean(&self, cx: &DocContext) -> Arguments {
|
||||
Arguments {
|
||||
values: self.0.iter().enumerate().map(|(i, ty)| {
|
||||
let mut name = self.1.get(i).map(|n| n.node.to_string())
|
||||
.unwrap_or(String::new());
|
||||
if name.is_empty() {
|
||||
name = "_".to_string();
|
||||
}
|
||||
Argument {
|
||||
name: name,
|
||||
type_: ty.clean(cx),
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Clean<Arguments> for (&'a [P<hir::Ty>], hir::BodyId) {
|
||||
fn clean(&self, cx: &DocContext) -> Arguments {
|
||||
let body = cx.tcx.map.body(self.1);
|
||||
|
||||
Arguments {
|
||||
values: self.0.iter().enumerate().map(|(i, ty)| {
|
||||
Argument {
|
||||
name: name_from_pat(&body.arguments[i].pat),
|
||||
type_: ty.clean(cx),
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, A: Copy> Clean<FnDecl> for (&'a hir::FnDecl, A)
|
||||
where (&'a [P<hir::Ty>], A): Clean<Arguments>
|
||||
{
|
||||
fn clean(&self, cx: &DocContext) -> FnDecl {
|
||||
FnDecl {
|
||||
inputs: Arguments {
|
||||
values: self.inputs.clean(cx),
|
||||
},
|
||||
output: self.output.clean(cx),
|
||||
variadic: self.variadic,
|
||||
inputs: (&self.0.inputs[..], self.1).clean(cx),
|
||||
output: self.0.output.clean(cx),
|
||||
variadic: self.0.variadic,
|
||||
attrs: Attributes::default()
|
||||
}
|
||||
}
|
||||
@ -1159,7 +1165,6 @@ impl<'a, 'tcx> Clean<FnDecl> for (DefId, &'a ty::PolyFnSig<'tcx>) {
|
||||
values: sig.skip_binder().inputs().iter().map(|t| {
|
||||
Argument {
|
||||
type_: t.clean(cx),
|
||||
id: ast::CRATE_NODE_ID,
|
||||
name: names.next().map_or("".to_string(), |name| name.to_string()),
|
||||
}
|
||||
}).collect(),
|
||||
@ -1172,7 +1177,6 @@ impl<'a, 'tcx> Clean<FnDecl> for (DefId, &'a ty::PolyFnSig<'tcx>) {
|
||||
pub struct Argument {
|
||||
pub type_: Type,
|
||||
pub name: String,
|
||||
pub id: ast::NodeId,
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
||||
@ -1199,16 +1203,6 @@ impl Argument {
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Argument> for hir::Arg {
|
||||
fn clean(&self, cx: &DocContext) -> Argument {
|
||||
Argument {
|
||||
name: name_from_pat(&*self.pat),
|
||||
type_: (self.ty.clean(cx)),
|
||||
id: self.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
||||
pub enum FunctionRetTy {
|
||||
Return(Type),
|
||||
@ -1274,11 +1268,16 @@ impl Clean<Item> for hir::TraitItem {
|
||||
AssociatedConstItem(ty.clean(cx),
|
||||
default.map(|e| print_const_expr(cx, e)))
|
||||
}
|
||||
hir::TraitItemKind::Method(ref sig, Some(_)) => {
|
||||
MethodItem(sig.clean(cx))
|
||||
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
|
||||
MethodItem((sig, body).clean(cx))
|
||||
}
|
||||
hir::TraitItemKind::Method(ref sig, None) => {
|
||||
TyMethodItem(sig.clean(cx))
|
||||
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => {
|
||||
TyMethodItem(TyMethod {
|
||||
unsafety: sig.unsafety.clone(),
|
||||
decl: (&*sig.decl, &names[..]).clean(cx),
|
||||
generics: sig.generics.clean(cx),
|
||||
abi: sig.abi
|
||||
})
|
||||
}
|
||||
hir::TraitItemKind::Type(ref bounds, ref default) => {
|
||||
AssociatedTypeItem(bounds.clean(cx), default.clean(cx))
|
||||
@ -1304,8 +1303,8 @@ impl Clean<Item> for hir::ImplItem {
|
||||
AssociatedConstItem(ty.clean(cx),
|
||||
Some(print_const_expr(cx, expr)))
|
||||
}
|
||||
hir::ImplItemKind::Method(ref sig, _) => {
|
||||
MethodItem(sig.clean(cx))
|
||||
hir::ImplItemKind::Method(ref sig, body) => {
|
||||
MethodItem((sig, body).clean(cx))
|
||||
}
|
||||
hir::ImplItemKind::Type(ref ty) => TypedefItem(Typedef {
|
||||
type_: ty.clean(cx),
|
||||
@ -2343,7 +2342,7 @@ impl Clean<BareFunctionDecl> for hir::BareFnTy {
|
||||
type_params: Vec::new(),
|
||||
where_predicates: Vec::new()
|
||||
},
|
||||
decl: self.decl.clean(cx),
|
||||
decl: (&*self.decl, &[][..]).clean(cx),
|
||||
abi: self.abi,
|
||||
}
|
||||
}
|
||||
@ -2641,9 +2640,9 @@ impl Clean<Vec<Item>> for hir::ForeignMod {
|
||||
impl Clean<Item> for hir::ForeignItem {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
let inner = match self.node {
|
||||
hir::ForeignItemFn(ref decl, ref generics) => {
|
||||
hir::ForeignItemFn(ref decl, ref names, ref generics) => {
|
||||
ForeignFunctionItem(Function {
|
||||
decl: decl.clean(cx),
|
||||
decl: (&**decl, &names[..]).clean(cx),
|
||||
generics: generics.clean(cx),
|
||||
unsafety: hir::Unsafety::Unsafe,
|
||||
abi: Abi::Rust,
|
||||
|
@ -156,6 +156,7 @@ pub struct Function {
|
||||
pub whence: Span,
|
||||
pub generics: hir::Generics,
|
||||
pub abi: abi::Abi,
|
||||
pub body: hir::BodyId,
|
||||
}
|
||||
|
||||
pub struct Typedef {
|
||||
|
@ -157,7 +157,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
unsafety: &hir::Unsafety,
|
||||
constness: hir::Constness,
|
||||
abi: &abi::Abi,
|
||||
gen: &hir::Generics) -> Function {
|
||||
gen: &hir::Generics,
|
||||
body: hir::BodyId) -> Function {
|
||||
debug!("Visiting fn");
|
||||
Function {
|
||||
id: item.id,
|
||||
@ -172,6 +173,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
unsafety: *unsafety,
|
||||
constness: constness,
|
||||
abi: *abi,
|
||||
body: body,
|
||||
}
|
||||
}
|
||||
|
||||
@ -410,9 +412,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
om.structs.push(self.visit_variant_data(item, name, sd, gen)),
|
||||
hir::ItemUnion(ref sd, ref gen) =>
|
||||
om.unions.push(self.visit_union_data(item, name, sd, gen)),
|
||||
hir::ItemFn(ref fd, ref unsafety, constness, ref abi, ref gen, _) =>
|
||||
hir::ItemFn(ref fd, ref unsafety, constness, ref abi, ref gen, body) =>
|
||||
om.fns.push(self.visit_fn(item, name, &**fd, unsafety,
|
||||
constness, abi, gen)),
|
||||
constness, abi, gen, body)),
|
||||
hir::ItemTy(ref ty, ref gen) => {
|
||||
let t = Typedef {
|
||||
ty: ty.clone(),
|
||||
|
@ -14,8 +14,8 @@ struct Foo<'a,'b> {
|
||||
}
|
||||
|
||||
impl<'a,'b> Foo<'a,'b> {
|
||||
fn bar(
|
||||
self
|
||||
fn bar(self:
|
||||
Foo<'b,'a>
|
||||
//~^ ERROR mismatched method receiver
|
||||
//~| expected type `Foo<'a, 'b>`
|
||||
//~| found type `Foo<'b, 'a>`
|
||||
@ -24,7 +24,7 @@ impl<'a,'b> Foo<'a,'b> {
|
||||
//~| expected type `Foo<'a, 'b>`
|
||||
//~| found type `Foo<'b, 'a>`
|
||||
//~| lifetime mismatch
|
||||
: Foo<'b,'a>) {}
|
||||
) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -158,6 +158,7 @@ trait TraitAddParameterToMethod {
|
||||
#[cfg(cfail1)]
|
||||
trait TraitChangeMethodParameterName {
|
||||
fn method(a: u32);
|
||||
fn with_default(x: i32) {}
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
@ -166,11 +167,20 @@ trait TraitChangeMethodParameterName {
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
trait TraitChangeMethodParameterName {
|
||||
// FIXME(#38501) This should preferably always be clean.
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn method(b: u32);
|
||||
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
fn with_default(y: i32) {}
|
||||
}
|
||||
|
||||
|
||||
@ -303,7 +313,7 @@ trait TraitChangeModeSelfOwnToMut: Sized {
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail2")]
|
||||
#[rustc_metadata_clean(cfg="cfail3")]
|
||||
trait TraitChangeModeSelfOwnToMut: Sized {
|
||||
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||
|
Loading…
Reference in New Issue
Block a user