rustc: move function arguments into hir::Body.

This commit is contained in:
Eduard-Mihai Burtescu 2016-12-20 22:46:11 +02:00
parent e64f64a2fc
commit f89856be6c
50 changed files with 545 additions and 568 deletions

View file

@ -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()
}

View file

@ -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()
}

View file

@ -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);

View file

@ -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"),

View file

@ -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
}
}

View file

@ -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),

View file

@ -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()
}

View file

@ -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[..]);
}

View file

@ -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
}
}

View file

@ -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,

View file

@ -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(..) => {}
}
}

View file

@ -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> {

View file

@ -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.

View file

@ -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(..) => {}

View file

@ -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 {

View file

@ -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 {

View file

@ -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)]

View file

@ -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;

View file

@ -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 ")));
}

View file

@ -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,

View file

@ -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));
}
}
}

View file

@ -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,

View file

@ -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
}
}

View file

@ -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));
}

View file

@ -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")
}
}

View file

@ -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, _) => {

View file

@ -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));
}
}

View file

@ -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)
}

View file

@ -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))
}

View file

@ -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);

View file

@ -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 };

View file

@ -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 {

View file

@ -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);

View file

@ -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
});

View file

@ -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)
}

View file

@ -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)
}
};

View file

@ -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
}

View file

@ -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
};

View file

@ -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);
});
}

View file

@ -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,

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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> {

View file

@ -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)

View file

@ -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
}

View file

@ -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,

View file

@ -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 {

View file

@ -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(),

View file

@ -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() {}

View file

@ -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")]