From e64f64a2fc1deb955b42542fa399f2fa2b609866 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 21 Dec 2016 12:32:59 +0200 Subject: [PATCH] rustc: separate bodies for static/(associated)const and embedded constants. --- src/librustc/cfg/construct.rs | 7 +- src/librustc/dep_graph/visit.rs | 1 - src/librustc/hir/intravisit.rs | 70 +++++------ src/librustc/hir/lowering.rs | 62 ++++++---- src/librustc/hir/map/blocks.rs | 14 +-- src/librustc/hir/map/collector.rs | 29 +++-- src/librustc/hir/map/def_collector.rs | 2 +- src/librustc/hir/map/definitions.rs | 3 +- src/librustc/hir/map/mod.rs | 40 +++++-- src/librustc/hir/mod.rs | 59 ++++----- src/librustc/hir/print.rs | 79 ++++++------ src/librustc/lint/context.rs | 9 +- src/librustc/lint/mod.rs | 4 +- src/librustc/middle/cstore.rs | 61 +++++----- src/librustc/middle/dataflow.rs | 8 +- src/librustc/middle/dead.rs | 12 +- src/librustc/middle/effect.rs | 2 +- src/librustc/middle/expr_use_visitor.rs | 9 +- src/librustc/middle/intrinsicck.rs | 18 +-- src/librustc/middle/liveness.rs | 30 ++--- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/middle/reachable.rs | 18 ++- src/librustc/middle/region.rs | 18 +-- src/librustc/middle/resolve_lifetime.rs | 12 +- src/librustc/ty/mod.rs | 8 +- src/librustc_borrowck/borrowck/check_loans.rs | 4 +- .../borrowck/gather_loans/mod.rs | 10 +- src/librustc_borrowck/borrowck/mir/mod.rs | 26 +--- src/librustc_borrowck/borrowck/mod.rs | 32 ++--- src/librustc_borrowck/borrowck/move_data.rs | 2 +- src/librustc_const_eval/check_match.rs | 4 +- src/librustc_const_eval/diagnostics.rs | 8 +- src/librustc_const_eval/eval.rs | 47 ++++---- src/librustc_driver/pretty.rs | 4 +- .../calculate_svh/svh_visitor.rs | 20 +++- src/librustc_lint/bad_style.rs | 2 +- src/librustc_lint/builtin.rs | 6 +- src/librustc_lint/unused.rs | 2 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_metadata/encoder.rs | 4 +- src/librustc_mir/build/mod.rs | 13 +- src/librustc_mir/hair/cx/expr.rs | 7 +- src/librustc_mir/mir_map.rs | 31 +++-- src/librustc_passes/consts.rs | 39 +++--- src/librustc_passes/hir_stats.rs | 2 +- src/librustc_passes/loops.rs | 2 +- src/librustc_passes/rvalues.rs | 4 +- src/librustc_passes/static_recursion.rs | 16 +-- src/librustc_resolve/lib.rs | 13 ++ src/librustc_typeck/astconv.rs | 5 +- src/librustc_typeck/check/closure.rs | 16 +-- src/librustc_typeck/check/mod.rs | 113 ++++++++---------- src/librustc_typeck/check/regionck.rs | 49 ++++---- src/librustc_typeck/check/upvar.rs | 27 +++-- src/librustc_typeck/check/wfcheck.rs | 4 +- src/librustc_typeck/check/writeback.rs | 19 ++- src/librustc_typeck/collect.rs | 3 +- src/librustc_typeck/diagnostics.rs | 39 ------ src/librustdoc/clean/mod.rs | 19 +-- src/librustdoc/doctree.rs | 4 +- src/test/compile-fail/E0513.rs | 19 --- ...ssociated-const-type-parameter-arrays-2.rs | 6 +- .../associated-const-type-parameter-arrays.rs | 4 +- src/test/compile-fail/issue-27008.rs | 2 - .../non-constant-expr-for-fixed-len-vec.rs | 4 +- .../non-constant-expr-for-vec-repeat.rs | 7 +- src/test/compile-fail/repeat_count.rs | 21 +--- src/test/incremental/hashes/consts.rs | 16 ++- src/test/incremental/hashes/enum_defs.rs | 6 +- src/test/incremental/hashes/statics.rs | 24 ++-- src/test/incremental/string_constant.rs | 4 +- .../issue-37290/auxiliary/lint.rs | 4 +- 72 files changed, 637 insertions(+), 655 deletions(-) delete mode 100644 src/test/compile-fail/E0513.rs diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index f21d98a0fc7..4d66bba9f07 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -327,10 +327,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { self.opt_expr(base, field_cfg) } - hir::ExprRepeat(ref elem, ref count) => { - self.straightline(expr, pred, [elem, count].iter().map(|&e| &**e)) - } - hir::ExprAssign(ref l, ref r) | hir::ExprAssignOp(_, ref l, ref r) => { self.straightline(expr, pred, [r, l].iter().map(|&e| &**e)) @@ -347,7 +343,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { hir::ExprType(ref e, _) | hir::ExprUnary(_, ref e) | hir::ExprField(ref e, _) | - hir::ExprTupField(ref e, _) => { + hir::ExprTupField(ref e, _) | + hir::ExprRepeat(ref e, _) => { self.straightline(expr, pred, Some(&**e).into_iter()) } diff --git a/src/librustc/dep_graph/visit.rs b/src/librustc/dep_graph/visit.rs index 61f58fc8fe5..1990574ca9a 100644 --- a/src/librustc/dep_graph/visit.rs +++ b/src/librustc/dep_graph/visit.rs @@ -50,7 +50,6 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx> let task_id = (self.dep_node_fn)(trait_item_def_id); let _task = self.tcx.dep_graph.in_task(task_id.clone()); debug!("Started task {:?}", task_id); - assert!(!self.tcx.map.is_inlined_def_id(trait_item_def_id)); self.tcx.dep_graph.read(DepNode::Hir(trait_item_def_id)); self.visitor.visit_trait_item(i); debug!("Ended task {:?}", task_id); diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index e16c97f2d25..845b6473259 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -203,10 +203,10 @@ pub trait Visitor<'v> : Sized { /// visit_nested_item, does nothing by default unless you override /// `nested_visit_map` to return `Some(_)`, in which case it will walk the /// body. - fn visit_body(&mut self, id: ExprId) { - let opt_expr = self.nested_visit_map().intra().map(|map| map.expr(id)); - if let Some(expr) = opt_expr { - self.visit_expr(expr); + fn visit_nested_body(&mut self, id: BodyId) { + let opt_body = self.nested_visit_map().intra().map(|map| map.body(id)); + if let Some(body) = opt_body { + self.visit_body(body); } } @@ -216,6 +216,10 @@ pub trait Visitor<'v> : Sized { walk_item(self, i) } + fn visit_body(&mut self, b: &'v Body) { + walk_body(self, b); + } + /// When invoking `visit_all_item_likes()`, you need to supply an /// item-like visitor. This method converts a "intra-visit" /// visitor into an item-like visitor that walks the entire tree. @@ -264,8 +268,6 @@ pub trait Visitor<'v> : Sized { fn visit_expr(&mut self, ex: &'v Expr) { walk_expr(self, ex) } - fn visit_expr_post(&mut self, _ex: &'v Expr) { - } fn visit_ty(&mut self, t: &'v Ty) { walk_ty(self, t) } @@ -278,7 +280,7 @@ pub trait Visitor<'v> : Sized { fn visit_fn_decl(&mut self, fd: &'v FnDecl) { walk_fn_decl(self, fd) } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: ExprId, s: Span, id: NodeId) { + fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: BodyId, s: Span, id: NodeId) { walk_fn(self, fk, fd, b, s, id) } fn visit_trait_item(&mut self, ti: &'v TraitItem) { @@ -392,6 +394,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) { + visitor.visit_expr(&body.value); +} + pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { visitor.visit_id(local.id); visitor.visit_pat(&local.pat); @@ -437,11 +443,11 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_id(item.id); visitor.visit_path(path, item.id); } - ItemStatic(ref typ, _, ref expr) | - ItemConst(ref typ, ref expr) => { + ItemStatic(ref typ, _, body) | + ItemConst(ref typ, body) => { visitor.visit_id(item.id); visitor.visit_ty(typ); - visitor.visit_expr(expr); + visitor.visit_nested_body(body); } ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => { visitor.visit_fn(FnKind::ItemFn(item.name, @@ -523,7 +529,7 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, generics, parent_item_id, variant.span); - walk_list!(visitor, visit_expr, &variant.node.disr_expr); + walk_list!(visitor, visit_nested_body, variant.node.disr_expr); walk_list!(visitor, visit_attribute, &variant.node.attrs); } @@ -556,9 +562,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { visitor.visit_ty(ty); walk_list!(visitor, visit_ty_param_bound, bounds); } - TyArray(ref ty, ref expression) => { + TyArray(ref ty, length) => { visitor.visit_ty(ty); - visitor.visit_expr(expression) + visitor.visit_nested_body(length) } TyPolyTraitRef(ref bounds) => { walk_list!(visitor, visit_ty_param_bound, bounds); @@ -566,8 +572,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { TyImplTrait(ref bounds) => { walk_list!(visitor, visit_ty_param_bound, bounds); } - TyTypeof(ref expression) => { - visitor.visit_expr(expression) + TyTypeof(expression) => { + visitor.visit_nested_body(expression) } TyInfer => {} } @@ -775,35 +781,23 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<' pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>, function_declaration: &'v FnDecl, - body_id: ExprId, + body_id: BodyId, _span: Span, id: NodeId) { visitor.visit_id(id); visitor.visit_fn_decl(function_declaration); walk_fn_kind(visitor, function_kind); - visitor.visit_body(body_id) -} - -pub fn walk_fn_with_body<'v, V: Visitor<'v>>(visitor: &mut V, - function_kind: FnKind<'v>, - function_declaration: &'v FnDecl, - body: &'v Expr, - _span: Span, - id: NodeId) { - visitor.visit_id(id); - visitor.visit_fn_decl(function_declaration); - walk_fn_kind(visitor, function_kind); - visitor.visit_expr(body) + visitor.visit_nested_body(body_id) } pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) { visitor.visit_name(trait_item.span, trait_item.name); walk_list!(visitor, visit_attribute, &trait_item.attrs); match trait_item.node { - TraitItemKind::Const(ref ty, ref default) => { + TraitItemKind::Const(ref ty, default) => { visitor.visit_id(trait_item.id); visitor.visit_ty(ty); - walk_list!(visitor, visit_expr, default); + walk_list!(visitor, visit_nested_body, default); } TraitItemKind::Method(ref sig, None) => { visitor.visit_id(trait_item.id); @@ -846,10 +840,10 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt visitor.visit_defaultness(defaultness); walk_list!(visitor, visit_attribute, attrs); match *node { - ImplItemKind::Const(ref ty, ref expr) => { + ImplItemKind::Const(ref ty, body) => { visitor.visit_id(impl_item.id); visitor.visit_ty(ty); - visitor.visit_expr(expr); + visitor.visit_nested_body(body); } ImplItemKind::Method(ref sig, body_id) => { visitor.visit_fn(FnKind::Method(impl_item.name, @@ -928,9 +922,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { ExprArray(ref subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } - ExprRepeat(ref element, ref count) => { + ExprRepeat(ref element, count) => { visitor.visit_expr(element); - visitor.visit_expr(count) + visitor.visit_nested_body(count) } ExprStruct(ref qpath, ref fields, ref optional_base) => { visitor.visit_qpath(qpath, expression.id, expression.span); @@ -1037,8 +1031,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { } } } - - visitor.visit_expr_post(expression) } pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { @@ -1125,12 +1117,12 @@ impl<'a, 'ast> Visitor<'ast> for IdRangeComputingVisitor<'a, 'ast> { /// 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: &'v Expr, + body: BodyId, sp: Span, id: NodeId, map: &map::Map<'v>) -> IdRange { let mut visitor = IdRangeComputingVisitor::new(map); - walk_fn_with_body(&mut visitor, fk, decl, body, sp, id); + visitor.visit_fn(fk, decl, body, sp, id); visitor.result() } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 75228811813..c858436e7fc 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -46,8 +46,7 @@ use hir::map::definitions::DefPathData; use hir::def_id::{DefIndex, DefId}; use hir::def::{Def, PathResolution}; use session::Session; -use util::nodemap::NodeMap; -use rustc_data_structures::fnv::FnvHashMap; +use util::nodemap::{NodeMap, FxHashMap}; use std::collections::BTreeMap; use std::iter; @@ -70,7 +69,6 @@ pub struct LoweringContext<'a> { // the form of a DefIndex) so that if we create a new node which introduces // a definition, then we can properly create the def id. parent_def: Option, - exprs: FnvHashMap, resolver: &'a mut Resolver, /// The items being lowered are collected here. @@ -78,6 +76,7 @@ pub struct LoweringContext<'a> { trait_items: BTreeMap, impl_items: BTreeMap, + bodies: FxHashMap, } pub trait Resolver { @@ -105,11 +104,11 @@ pub fn lower_crate(sess: &Session, crate_root: std_inject::injected_crate_name(krate), sess: sess, parent_def: None, - exprs: FnvHashMap(), resolver: resolver, items: BTreeMap::new(), trait_items: BTreeMap::new(), impl_items: BTreeMap::new(), + bodies: FxHashMap(), }.lower_crate(krate) } @@ -136,7 +135,7 @@ impl<'a> LoweringContext<'a> { items: self.items, trait_items: self.trait_items, impl_items: self.impl_items, - exprs: self.exprs, + bodies: self.bodies, } } @@ -171,9 +170,12 @@ impl<'a> LoweringContext<'a> { visit::walk_crate(&mut item_lowerer, c); } - fn record_expr(&mut self, expr: hir::Expr) -> hir::ExprId { - let id = hir::ExprId(expr.id); - self.exprs.insert(id, expr); + fn record_body(&mut self, value: hir::Expr) -> hir::BodyId { + let body = hir::Body { + value: value + }; + let id = body.id(); + self.bodies.insert(id, body); id } @@ -305,11 +307,14 @@ impl<'a> LoweringContext<'a> { TyKind::ObjectSum(ref ty, ref bounds) => { hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds)) } - TyKind::Array(ref ty, ref e) => { - hir::TyArray(self.lower_ty(ty), P(self.lower_expr(e))) + TyKind::Array(ref ty, ref length) => { + let length = self.lower_expr(length); + hir::TyArray(self.lower_ty(ty), + self.record_body(length)) } TyKind::Typeof(ref expr) => { - hir::TyTypeof(P(self.lower_expr(expr))) + let expr = self.lower_expr(expr); + hir::TyTypeof(self.record_body(expr)) } TyKind::PolyTraitRef(ref bounds) => { hir::TyPolyTraitRef(self.lower_bounds(bounds)) @@ -336,7 +341,10 @@ impl<'a> LoweringContext<'a> { name: v.node.name.name, attrs: self.lower_attrs(&v.node.attrs), data: self.lower_variant_data(&v.node.data), - disr_expr: v.node.disr_expr.as_ref().map(|e| P(self.lower_expr(e))), + disr_expr: v.node.disr_expr.as_ref().map(|e| { + let e = self.lower_expr(e); + self.record_body(e) + }), }, span: v.span, } @@ -858,17 +866,20 @@ impl<'a> LoweringContext<'a> { hir::ItemUse(path, kind) } ItemKind::Static(ref t, m, ref e) => { + let value = self.lower_expr(e); hir::ItemStatic(self.lower_ty(t), self.lower_mutability(m), - P(self.lower_expr(e))) + self.record_body(value)) } ItemKind::Const(ref t, ref e) => { - hir::ItemConst(self.lower_ty(t), P(self.lower_expr(e))) + let value = self.lower_expr(e); + hir::ItemConst(self.lower_ty(t), + self.record_body(value)) } 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_expr(body); + let body_id = self.record_body(body); hir::ItemFn(self.lower_fn_decl(decl), self.lower_unsafety(unsafety), self.lower_constness(constness), @@ -935,14 +946,17 @@ impl<'a> LoweringContext<'a> { node: match i.node { TraitItemKind::Const(ref ty, ref default) => { hir::TraitItemKind::Const(this.lower_ty(ty), - default.as_ref().map(|x| P(this.lower_expr(x)))) + default.as_ref().map(|x| { + let value = this.lower_expr(x); + this.record_body(value) + })) } TraitItemKind::Method(ref sig, ref body) => { 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_expr(expr) + this.record_body(expr) })) } TraitItemKind::Type(ref bounds, ref default) => { @@ -990,13 +1004,15 @@ impl<'a> LoweringContext<'a> { defaultness: this.lower_defaultness(i.defaultness, true /* [1] */), node: match i.node { ImplItemKind::Const(ref ty, ref expr) => { - hir::ImplItemKind::Const(this.lower_ty(ty), P(this.lower_expr(expr))) + let value = this.lower_expr(expr); + let body_id = this.record_body(value); + 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 expr_id = this.record_expr(expr); - hir::ImplItemKind::Method(this.lower_method_sig(sig), expr_id) + let body_id = this.record_body(expr); + hir::ImplItemKind::Method(this.lower_method_sig(sig), body_id) } ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)), ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), @@ -1350,8 +1366,8 @@ impl<'a> LoweringContext<'a> { } ExprKind::Repeat(ref expr, ref count) => { let expr = P(self.lower_expr(expr)); - let count = P(self.lower_expr(count)); - hir::ExprRepeat(expr, count) + let count = self.lower_expr(count); + hir::ExprRepeat(expr, self.record_body(count)) } ExprKind::Tup(ref elts) => { hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect()) @@ -1434,7 +1450,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_expr(expr), + this.record_body(expr), fn_decl_span) }) } diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index 8df4d669d0c..001a4d1526d 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -48,7 +48,7 @@ pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; } /// Components shared by fn-like things (fn items, methods, closures). pub struct FnParts<'a> { pub decl: &'a FnDecl, - pub body: ast::ExprId, + pub body: ast::BodyId, pub kind: FnKind<'a>, pub span: Span, pub id: NodeId, @@ -115,7 +115,7 @@ struct ItemFnParts<'a> { abi: abi::Abi, vis: &'a ast::Visibility, generics: &'a ast::Generics, - body: ast::ExprId, + body: ast::BodyId, id: NodeId, span: Span, attrs: &'a [Attribute], @@ -125,14 +125,14 @@ struct ItemFnParts<'a> { /// for use when implementing FnLikeNode operations. struct ClosureParts<'a> { decl: &'a FnDecl, - body: ast::ExprId, + body: ast::BodyId, id: NodeId, span: Span, attrs: &'a [Attribute], } impl<'a> ClosureParts<'a> { - fn new(d: &'a FnDecl, b: ast::ExprId, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self { + fn new(d: &'a FnDecl, b: ast::BodyId, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self { ClosureParts { decl: d, body: b, @@ -172,9 +172,9 @@ impl<'a> FnLikeNode<'a> { } } - pub fn body(self) -> ast::ExprId { + pub fn body(self) -> ast::BodyId { self.handle(|i: ItemFnParts<'a>| i.body, - |_, _, _: &'a ast::MethodSig, _, body: ast::ExprId, _, _| body, + |_, _, _: &'a ast::MethodSig, _, body: ast::BodyId, _, _| body, |c: ClosureParts<'a>| c.body) } @@ -227,7 +227,7 @@ impl<'a> FnLikeNode<'a> { Name, &'a ast::MethodSig, Option<&'a ast::Visibility>, - ast::ExprId, + ast::BodyId, Span, &'a [Attribute]) -> A, diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 9a4047f70e3..d138ffe6226 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -99,15 +99,21 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } fn visit_nested_trait_item(&mut self, item_id: TraitItemId) { - self.visit_trait_item(self.krate.trait_item(item_id)) + if !self.ignore_nested_items { + self.visit_trait_item(self.krate.trait_item(item_id)) + } } fn visit_nested_impl_item(&mut self, item_id: ImplItemId) { - self.visit_impl_item(self.krate.impl_item(item_id)) + if !self.ignore_nested_items { + self.visit_impl_item(self.krate.impl_item(item_id)) + } } - fn visit_body(&mut self, id: ExprId) { - self.visit_expr(self.krate.expr(id)) + fn visit_nested_body(&mut self, id: BodyId) { + if !self.ignore_nested_items { + self.visit_body(self.krate.body(id)) + } } fn visit_item(&mut self, i: &'ast Item) { @@ -117,11 +123,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.with_parent(i.id, |this| { match i.node { - ItemEnum(ref enum_definition, _) => { - for v in &enum_definition.variants { - this.insert(v.node.data.id(), NodeVariant(v)); - } - } ItemStruct(ref struct_def, _) => { // If this is a tuple-like struct, register the constructor. if !struct_def.is_struct() { @@ -213,7 +214,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, - b: ExprId, s: Span, id: NodeId) { + b: BodyId, s: Span, id: NodeId) { assert_eq!(self.parent_node, id); intravisit::walk_fn(self, fk, fd, b, s, id); } @@ -247,6 +248,14 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.insert_entry(macro_def.id, NotPresent); } + fn visit_variant(&mut self, v: &'ast Variant, g: &'ast Generics, item_id: NodeId) { + let id = v.node.data.id(); + self.insert(id, NodeVariant(v)); + self.with_parent(id, |this| { + intravisit::walk_variant(this, v, g, item_id); + }); + } + fn visit_struct_field(&mut self, field: &'ast StructField) { self.insert(field.id, NodeField(field)); self.with_parent(field.id, |this| { diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 256aee342a3..be8780f39b1 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -16,7 +16,7 @@ use syntax::ext::hygiene::Mark; use syntax::visit; use syntax::symbol::{Symbol, keywords}; -/// Creates def ids for nodes in the HIR. +/// Creates def ids for nodes in the AST. pub struct DefCollector<'a> { definitions: &'a mut Definitions, parent_def: Option, diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 4f64670f482..b28c5e80ea3 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -220,7 +220,6 @@ impl DefPath { } } - #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum DefPathData { // Root: these should only be used for the root nodes, because @@ -339,7 +338,7 @@ impl Definitions { data, self.table.def_key(self.node_to_def_index[&node_id])); - assert!(parent.is_some() ^ (data == DefPathData::CrateRoot)); + assert_eq!(parent.is_some(), data != DefPathData::CrateRoot); // Find a unique DefKey. This basically means incrementing the disambiguator // until we get no match. diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index a6ead8efe51..ff9d12bb4f1 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -266,7 +266,6 @@ impl<'ast> Map<'ast> { EntryTraitItem(_, item) => { let def_id = self.local_def_id(id); - assert!(!self.is_inlined_def_id(def_id)); if let Some(last_id) = last_expr { // The body of the item may have a separate dep node @@ -289,8 +288,19 @@ impl<'ast> Map<'ast> { return DepNode::Hir(def_id); } + EntryVariant(p, v) => { + id = p; + + if last_expr.is_some() { + if v.node.disr_expr.map(|e| e.node_id) == last_expr { + // The enum parent holds both Hir and HirBody nodes. + let def_id = self.local_def_id(id); + return DepNode::HirBody(def_id); + } + } + } + EntryForeignItem(p, _) | - EntryVariant(p, _) | EntryField(p, _) | EntryStmt(p, _) | EntryTy(p, _) | @@ -317,7 +327,7 @@ impl<'ast> Map<'ast> { bug!("node {} has inlined ancestor but is not inlined", id0), NotPresent => - // Some nodes, notably struct fields, are not + // Some nodes, notably macro definitions, are not // present in the map for whatever reason, but // they *do* have def-ids. So if we encounter an // empty hole, check for that case. @@ -369,21 +379,25 @@ impl<'ast> Map<'ast> { fn is_item_body(&self, node_id: NodeId, item: &Item) -> bool { match item.node { - ItemFn(_, _, _, _, _, body) => body.node_id() == node_id, + ItemConst(_, body) | + ItemStatic(.., body) | + ItemFn(_, _, _, _, _, body) => body.node_id == node_id, _ => false } } fn is_trait_item_body(&self, node_id: NodeId, item: &TraitItem) -> bool { match item.node { - TraitItemKind::Method(_, Some(body)) => body.node_id() == node_id, + TraitItemKind::Const(_, Some(body)) | + TraitItemKind::Method(_, Some(body)) => body.node_id == node_id, _ => false } } fn is_impl_item_body(&self, node_id: NodeId, item: &ImplItem) -> bool { match item.node { - ImplItemKind::Method(_, body) => body.node_id() == node_id, + ImplItemKind::Const(_, body) | + ImplItemKind::Method(_, body) => body.node_id == node_id, _ => false } } @@ -459,6 +473,14 @@ impl<'ast> Map<'ast> { self.forest.krate.impl_item(id) } + pub fn body(&self, id: BodyId) -> &'ast Body { + self.read(id.node_id); + + // NB: intentionally bypass `self.forest.krate()` so that we + // do not trigger a read of the whole krate here + self.forest.krate.body(id) + } + /// Get the attributes on the krate. This is preferable to /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. @@ -709,10 +731,6 @@ impl<'ast> Map<'ast> { } } - pub fn expr(&self, id: ExprId) -> &'ast Expr { - self.expect_expr(id.node_id()) - } - /// Returns the name associated with the given NodeId's AST. pub fn name(&self, id: NodeId) -> Name { match self.get(id) { @@ -793,7 +811,7 @@ impl<'ast> Map<'ast> { Some(EntryVisibility(_, v)) => bug!("unexpected Visibility {:?}", v), Some(RootCrate) => self.forest.krate.span, - Some(RootInlinedParent(parent)) => parent.body.span, + Some(RootInlinedParent(parent)) => parent.body.value.span, Some(NotPresent) | None => { bug!("hir::map::Map::span: id not in map: {:?}", id) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index db65d34e3d9..b4a42711e4d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -31,8 +31,7 @@ pub use self::PathParameters::*; use hir::def::Def; use hir::def_id::DefId; -use util::nodemap::{NodeMap, FxHashSet}; -use rustc_data_structures::fnv::FnvHashMap; +use util::nodemap::{NodeMap, FxHashMap, FxHashSet}; use syntax_pos::{Span, ExpnId, DUMMY_SP}; use syntax::codemap::{self, Spanned}; @@ -40,7 +39,7 @@ use syntax::abi::Abi; use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect}; use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem}; use syntax::ptr::P; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, keywords}; use syntax::tokenstream::TokenTree; use syntax::util::ThinVec; @@ -432,7 +431,7 @@ pub struct Crate { pub trait_items: BTreeMap, pub impl_items: BTreeMap, - pub exprs: FnvHashMap, + pub bodies: FxHashMap, } impl Crate { @@ -472,8 +471,8 @@ impl Crate { } } - pub fn expr(&self, id: ExprId) -> &Expr { - &self.exprs[&id] + pub fn body(&self, id: BodyId) -> &Body { + &self.bodies[&id] } } @@ -862,11 +861,21 @@ pub enum UnsafeSource { } #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct ExprId(NodeId); +pub struct BodyId { + pub node_id: NodeId, +} -impl ExprId { - pub fn node_id(self) -> NodeId { - self.0 +/// The body of a function or constant value. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Body { + pub value: Expr +} + +impl Body { + pub fn id(&self) -> BodyId { + BodyId { + node_id: self.value.id + } } } @@ -879,12 +888,6 @@ pub struct Expr { pub attrs: ThinVec, } -impl Expr { - pub fn expr_id(&self) -> ExprId { - ExprId(self.id) - } -} - impl fmt::Debug for Expr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "expr({}: {})", self.id, print::expr_to_string(self)) @@ -944,7 +947,7 @@ pub enum Expr_ { /// A closure (for example, `move |a, b, c| {a + b + c}`). /// /// The final span is the span of the argument block `|...|` - ExprClosure(CaptureClause, P, ExprId, Span), + ExprClosure(CaptureClause, P, BodyId, Span), /// A block (`{ ... }`) ExprBlock(P), @@ -988,7 +991,7 @@ pub enum Expr_ { /// /// For example, `[1; 5]`. The first expression is the element /// to be repeated; the second is the number of times to repeat it. - ExprRepeat(P, P), + ExprRepeat(P, BodyId), } /// Optionally `Self`-qualified value/type path or associated extension. @@ -1104,9 +1107,9 @@ pub struct TraitItem { pub enum TraitItemKind { /// An associated constant with an optional value (otherwise `impl`s /// must contain a value) - Const(P, Option>), + Const(P, Option), /// A method with an optional body - Method(MethodSig, Option), + Method(MethodSig, Option), /// An associated type with (possibly empty) bounds and optional concrete /// type Type(TyParamBounds, Option>), @@ -1137,9 +1140,9 @@ pub struct ImplItem { pub enum ImplItemKind { /// An associated constant of the given type, set to the constant result /// of the expression - Const(P, P), + Const(P, BodyId), /// A method implementation with the given signature and body - Method(MethodSig, ExprId), + Method(MethodSig, BodyId), /// An associated type Type(P), } @@ -1192,7 +1195,7 @@ pub enum Ty_ { /// A variable length slice (`[T]`) TySlice(P), /// A fixed length array (`[T; n]`) - TyArray(P, P), + TyArray(P, BodyId), /// A raw pointer (`*const T` or `*mut T`) TyPtr(MutTy), /// A reference (`&'a T` or `&'a mut T`) @@ -1216,7 +1219,7 @@ pub enum Ty_ { /// An `impl TraitA+TraitB` type. TyImplTrait(TyParamBounds), /// Unused for now - TyTypeof(P), + TyTypeof(BodyId), /// TyInfer means the type should be inferred instead of it having been /// specified. This can appear anywhere in a type. TyInfer, @@ -1371,7 +1374,7 @@ pub struct Variant_ { pub attrs: HirVec, pub data: VariantData, /// Explicit discriminant, eg `Foo = 1` - pub disr_expr: Option>, + pub disr_expr: Option, } pub type Variant = Spanned; @@ -1530,11 +1533,11 @@ pub enum Item_ { ItemUse(P, UseKind), /// A `static` item - ItemStatic(P, Mutability, P), + ItemStatic(P, Mutability, BodyId), /// A `const` item - ItemConst(P, P), + ItemConst(P, BodyId), /// A function declaration - ItemFn(P, Unsafety, Constness, Abi, Generics, ExprId), + ItemFn(P, Unsafety, Constness, Abi, Generics, BodyId), /// A module ItemMod(Mod), /// An external module diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 745ab4e6372..9518113b5a0 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -462,7 +462,7 @@ impl<'a> State<'a> { pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) -> io::Result<()> { self.print_inner_attributes(attrs)?; - for item_id in &_mod.item_ids { + for &item_id in &_mod.item_ids { self.print_item_id(item_id)?; } Ok(()) @@ -545,16 +545,16 @@ impl<'a> State<'a> { hir::TyImplTrait(ref bounds) => { self.print_bounds("impl ", &bounds[..])?; } - hir::TyArray(ref ty, ref v) => { + hir::TyArray(ref ty, v) => { word(&mut self.s, "[")?; self.print_type(&ty)?; word(&mut self.s, "; ")?; - self.print_expr(&v)?; + self.print_body_id(v)?; word(&mut self.s, "]")?; } - hir::TyTypeof(ref e) => { + hir::TyTypeof(e) => { word(&mut self.s, "typeof(")?; - self.print_expr(&e)?; + self.print_body_id(e)?; word(&mut self.s, ")")?; } hir::TyInfer => { @@ -600,7 +600,7 @@ impl<'a> State<'a> { fn print_associated_const(&mut self, name: ast::Name, ty: &hir::Ty, - default: Option<&hir::Expr>, + default: Option, vis: &hir::Visibility) -> io::Result<()> { word(&mut self.s, &visibility_qualified(vis, ""))?; @@ -611,7 +611,7 @@ impl<'a> State<'a> { if let Some(expr) = default { space(&mut self.s)?; self.word_space("=")?; - self.print_expr(expr)?; + self.print_body_id(expr)?; } word(&mut self.s, ";") } @@ -634,7 +634,7 @@ impl<'a> State<'a> { word(&mut self.s, ";") } - pub fn print_item_id(&mut self, item_id: &hir::ItemId) -> io::Result<()> { + pub fn print_item_id(&mut self, item_id: hir::ItemId) -> io::Result<()> { if let Some(krate) = self.krate { // skip nested items if krate context was not provided let item = &krate.items[&item_id.id]; @@ -644,9 +644,9 @@ impl<'a> State<'a> { } } - pub fn print_expr_id(&mut self, expr_id: &hir::ExprId) -> io::Result<()> { + fn print_body_id(&mut self, body_id: hir::BodyId) -> io::Result<()> { if let Some(krate) = self.krate { - let expr = &krate.exprs[expr_id]; + let expr = &krate.body(body_id).value; self.print_expr(expr) } else { Ok(()) @@ -697,7 +697,7 @@ impl<'a> State<'a> { self.end()?; // end inner head-block self.end()?; // end outer head-block } - hir::ItemStatic(ref ty, m, ref expr) => { + hir::ItemStatic(ref ty, m, expr) => { self.head(&visibility_qualified(&item.vis, "static"))?; if m == hir::MutMutable { self.word_space("mut")?; @@ -709,11 +709,11 @@ impl<'a> State<'a> { self.end()?; // end the head-ibox self.word_space("=")?; - self.print_expr(&expr)?; + self.print_body_id(expr)?; word(&mut self.s, ";")?; self.end()?; // end the outer cbox } - hir::ItemConst(ref ty, ref expr) => { + hir::ItemConst(ref ty, expr) => { self.head(&visibility_qualified(&item.vis, "const"))?; self.print_name(item.name)?; self.word_space(":")?; @@ -722,11 +722,11 @@ impl<'a> State<'a> { self.end()?; // end the head-ibox self.word_space("=")?; - self.print_expr(&expr)?; + self.print_body_id(expr)?; word(&mut self.s, ";")?; self.end()?; // end the outer cbox } - hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, ref body) => { + hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, body) => { self.head("")?; self.print_fn(decl, unsafety, @@ -738,7 +738,7 @@ impl<'a> State<'a> { word(&mut self.s, " ")?; self.end()?; // need to close a box self.end()?; // need to close a box - self.print_expr_id(body)?; + self.print_body_id(body)?; } hir::ItemMod(ref _mod) => { self.head(&visibility_qualified(&item.vis, "mod"))?; @@ -985,14 +985,12 @@ impl<'a> State<'a> { self.head("")?; let generics = hir::Generics::empty(); self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?; - match v.node.disr_expr { - Some(ref d) => { - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(&d) - } - _ => Ok(()), + if let Some(d) = v.node.disr_expr { + space(&mut self.s)?; + self.word_space("=")?; + self.print_body_id(d)?; } + Ok(()) } pub fn print_method_sig(&mut self, name: ast::Name, @@ -1024,22 +1022,19 @@ impl<'a> State<'a> { self.maybe_print_comment(ti.span.lo)?; self.print_outer_attributes(&ti.attrs)?; match ti.node { - hir::TraitItemKind::Const(ref ty, ref default) => { - self.print_associated_const(ti.name, - &ty, - default.as_ref().map(|expr| &**expr), - &hir::Inherited)?; + hir::TraitItemKind::Const(ref ty, default) => { + self.print_associated_const(ti.name, &ty, default, &hir::Inherited)?; } - hir::TraitItemKind::Method(ref sig, ref body) => { + hir::TraitItemKind::Method(ref sig, body) => { if body.is_some() { self.head("")?; } self.print_method_sig(ti.name, sig, &hir::Inherited)?; - if let Some(ref body) = *body { + if let Some(body) = body { self.nbsp()?; self.end()?; // need to close a box self.end()?; // need to close a box - self.print_expr_id(body)?; + self.print_body_id(body)?; } else { word(&mut self.s, ";")?; } @@ -1075,16 +1070,16 @@ impl<'a> State<'a> { } match ii.node { - hir::ImplItemKind::Const(ref ty, ref expr) => { - self.print_associated_const(ii.name, &ty, Some(&expr), &ii.vis)?; + hir::ImplItemKind::Const(ref ty, expr) => { + self.print_associated_const(ii.name, &ty, Some(expr), &ii.vis)?; } - hir::ImplItemKind::Method(ref sig, ref body) => { + hir::ImplItemKind::Method(ref sig, body) => { self.head("")?; self.print_method_sig(ii.name, sig, &ii.vis)?; self.nbsp()?; self.end()?; // need to close a box self.end()?; // need to close a box - self.print_expr_id(body)?; + self.print_body_id(body)?; } hir::ImplItemKind::Type(ref ty) => { self.print_associated_type(ii.name, None, Some(ty))?; @@ -1256,12 +1251,12 @@ impl<'a> State<'a> { self.end() } - fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::Expr) -> io::Result<()> { + fn print_expr_repeat(&mut self, element: &hir::Expr, count: hir::BodyId) -> io::Result<()> { self.ibox(indent_unit)?; word(&mut self.s, "[")?; self.print_expr(element)?; self.word_space(";")?; - self.print_expr(count)?; + self.print_body_id(count)?; word(&mut self.s, "]")?; self.end() } @@ -1372,8 +1367,8 @@ impl<'a> State<'a> { hir::ExprArray(ref exprs) => { self.print_expr_vec(exprs)?; } - hir::ExprRepeat(ref element, ref count) => { - self.print_expr_repeat(&element, &count)?; + hir::ExprRepeat(ref element, count) => { + self.print_expr_repeat(&element, count)?; } hir::ExprStruct(ref qpath, ref fields, ref wth) => { self.print_expr_struct(qpath, &fields[..], wth)?; @@ -1444,14 +1439,14 @@ impl<'a> State<'a> { } self.bclose_(expr.span, indent_unit)?; } - hir::ExprClosure(capture_clause, ref decl, ref body, _fn_decl_span) => { + hir::ExprClosure(capture_clause, ref decl, body, _fn_decl_span) => { self.print_capture_clause(capture_clause)?; self.print_fn_block_args(&decl)?; space(&mut self.s)?; // this is a bare expression - self.print_expr_id(body)?; + self.print_body_id(body)?; self.end()?; // need to close a box // a box will be closed by print_expr, but we didn't want an overall @@ -1625,7 +1620,7 @@ impl<'a> State<'a> { } self.end() } - hir::DeclItem(ref item) => { + hir::DeclItem(item) => { self.print_item_id(item) } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 3ff2abac277..cce79820ca8 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -821,6 +821,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { self.with_lint_attrs(&e.attrs, |cx| { run_lints!(cx, check_expr, late_passes, e); hir_visit::walk_expr(cx, e); + run_lints!(cx, check_expr_post, late_passes, e); }) } @@ -835,8 +836,8 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { } fn visit_fn(&mut self, fk: hir_visit::FnKind<'tcx>, decl: &'tcx hir::FnDecl, - body_id: hir::ExprId, span: Span, id: ast::NodeId) { - let body = self.tcx.map.expr(body_id); + body_id: hir::BodyId, span: Span, id: ast::NodeId) { + let body = self.tcx.map.body(body_id); run_lints!(self, check_fn, late_passes, fk, decl, body, span, id); hir_visit::walk_fn(self, fk, decl, body_id, span, id); run_lints!(self, check_fn_post, late_passes, fk, decl, body, span, id); @@ -909,10 +910,6 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { hir_visit::walk_decl(self, d); } - fn visit_expr_post(&mut self, e: &'tcx hir::Expr) { - run_lints!(self, check_expr_post, late_passes, e); - } - fn visit_generics(&mut self, g: &'tcx hir::Generics) { run_lints!(self, check_generics, late_passes, g); hir_visit::walk_generics(self, g); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index ccf53f01cd5..7e0da00694c 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -162,14 +162,14 @@ pub trait LateLintPass<'a, 'tcx>: LintPass { _: &LateContext<'a, 'tcx>, _: FnKind<'tcx>, _: &'tcx hir::FnDecl, - _: &'tcx hir::Expr, + _: &'tcx hir::Body, _: Span, _: ast::NodeId) { } fn check_fn_post(&mut self, _: &LateContext<'a, 'tcx>, _: FnKind<'tcx>, _: &'tcx hir::FnDecl, - _: &'tcx hir::Expr, + _: &'tcx hir::Body, _: Span, _: ast::NodeId) { } fn check_trait_item(&mut self, _: &LateContext<'a, 'tcx>, _: &'tcx hir::TraitItem) { } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 7d570596386..4c2e43f8e22 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -38,7 +38,6 @@ use std::rc::Rc; use syntax::ast; use syntax::attr; use syntax::ext::base::SyntaxExtension; -use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; use rustc_back::target::Target; @@ -140,7 +139,7 @@ pub struct NativeLibrary { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct InlinedItem { pub def_id: DefId, - pub body: P, + pub body: hir::Body, pub const_fn_args: Vec>, } @@ -149,7 +148,7 @@ pub struct InlinedItem { #[derive(Clone, PartialEq, Eq, RustcEncodable, Hash, Debug)] pub struct InlinedItemRef<'a> { pub def_id: DefId, - pub body: &'a hir::Expr, + pub body: &'a hir::Body, pub const_fn_args: Vec>, } @@ -160,31 +159,31 @@ fn get_fn_args(decl: &hir::FnDecl) -> Vec> { }).collect() } -impl<'a> InlinedItemRef<'a> { - pub fn from_item<'b, 'tcx>(def_id: DefId, - item: &'a hir::Item, - tcx: TyCtxt<'b, 'a, 'tcx>) - -> InlinedItemRef<'a> { - let (body, args) = match item.node { +impl<'a, 'tcx> InlinedItemRef<'tcx> { + pub fn from_item(def_id: DefId, + item: &hir::Item, + tcx: TyCtxt<'a, 'tcx, 'tcx>) + -> InlinedItemRef<'tcx> { + let (body_id, args) = match item.node { hir::ItemFn(ref decl, _, _, _, _, body_id) => - (tcx.map.expr(body_id), get_fn_args(decl)), - hir::ItemConst(_, ref body) => (&**body, Vec::new()), + (body_id, get_fn_args(decl)), + hir::ItemConst(_, body_id) => (body_id, vec![]), _ => bug!("InlinedItemRef::from_item wrong kind") }; InlinedItemRef { def_id: def_id, - body: body, + body: tcx.map.body(body_id), const_fn_args: args } } pub fn from_trait_item(def_id: DefId, - item: &'a hir::TraitItem, - _tcx: TyCtxt) - -> InlinedItemRef<'a> { - let (body, args) = match item.node { - hir::TraitItemKind::Const(_, Some(ref body)) => - (&**body, Vec::new()), + 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![]), hir::TraitItemKind::Const(_, None) => { bug!("InlinedItemRef::from_trait_item called for const without body") }, @@ -192,33 +191,33 @@ impl<'a> InlinedItemRef<'a> { }; InlinedItemRef { def_id: def_id, - body: body, + body: tcx.map.body(body_id), const_fn_args: args } } - pub fn from_impl_item<'b, 'tcx>(def_id: DefId, - item: &'a hir::ImplItem, - tcx: TyCtxt<'b, 'a, 'tcx>) - -> InlinedItemRef<'a> { - let (body, args) = match item.node { + pub fn from_impl_item(def_id: DefId, + item: &hir::ImplItem, + tcx: TyCtxt<'a, 'tcx, 'tcx>) + -> InlinedItemRef<'tcx> { + let (body_id, args) = match item.node { hir::ImplItemKind::Method(ref sig, body_id) => - (tcx.map.expr(body_id), get_fn_args(&sig.decl)), - hir::ImplItemKind::Const(_, ref body) => - (&**body, Vec::new()), + (body_id, get_fn_args(&sig.decl)), + hir::ImplItemKind::Const(_, body_id) => + (body_id, vec![]), _ => bug!("InlinedItemRef::from_impl_item wrong kind") }; InlinedItemRef { def_id: def_id, - body: body, + body: tcx.map.body(body_id), const_fn_args: args } } pub fn visit(&self, visitor: &mut V) - where V: Visitor<'a> + where V: Visitor<'tcx> { - visitor.visit_expr(&self.body); + visitor.visit_body(self.body); } } @@ -226,7 +225,7 @@ impl InlinedItem { pub fn visit<'ast,V>(&'ast self, visitor: &mut V) where V: Visitor<'ast> { - visitor.visit_expr(&self.body); + visitor.visit_body(&self.body); } } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index f7a34c43ccc..8705393849a 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -194,7 +194,7 @@ fn build_nodeid_to_index(decl: Option<&hir::FnDecl>, intravisit::walk_fn_decl(&mut formals, decl); impl<'a, 'v> intravisit::Visitor<'v> for Formals<'a> { fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v> { - panic!("should not encounter fn bodies or items") + intravisit::NestedVisitorMap::None } fn visit_pat(&mut self, p: &hir::Pat) { @@ -502,7 +502,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> { // ^^^^^^^^^^^^^ only needed for pretty printing - pub fn propagate(&mut self, cfg: &cfg::CFG, body: &hir::Expr) { + pub fn propagate(&mut self, cfg: &cfg::CFG, body: &hir::Body) { //! Performs the data flow analysis. if self.bits_per_id == 0 { @@ -534,11 +534,11 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> { } fn pretty_print_to<'b>(&self, wr: Box, - body: &hir::Expr) -> io::Result<()> { + body: &hir::Body) -> io::Result<()> { let mut ps = pprust::rust_printer_annotated(wr, self, None); ps.cbox(pprust::indent_unit)?; ps.ibox(0)?; - ps.print_expr(body)?; + ps.print_expr(&body.value)?; pp::eof(&mut ps.s) } } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 2206336164a..926975d1423 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -551,19 +551,19 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { match impl_item.node { - hir::ImplItemKind::Const(_, ref expr) => { + hir::ImplItemKind::Const(_, body_id) => { if !self.symbol_is_live(impl_item.id, None) { self.warn_dead_code(impl_item.id, impl_item.span, impl_item.name, "associated const"); } - intravisit::walk_expr(self, expr) + self.visit_nested_body(body_id) } hir::ImplItemKind::Method(_, body_id) => { if !self.symbol_is_live(impl_item.id, None) { self.warn_dead_code(impl_item.id, impl_item.span, impl_item.name, "method"); } - self.visit_body(body_id) + self.visit_nested_body(body_id) } hir::ImplItemKind::Type(..) => {} } @@ -572,11 +572,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { // Overwrite so that we don't warn the trait item itself. fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { match trait_item.node { - hir::TraitItemKind::Const(_, Some(ref body)) => { - intravisit::walk_expr(self, body) - } + hir::TraitItemKind::Const(_, Some(body_id)) | hir::TraitItemKind::Method(_, Some(body_id)) => { - self.visit_body(body_id) + self.visit_nested_body(body_id) } hir::TraitItemKind::Const(_, None) | hir::TraitItemKind::Method(_, None) | diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 2ec7aa4c4d9..38b0b18b012 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -98,7 +98,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> { } fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl, - body_id: hir::ExprId, span: Span, id: ast::NodeId) { + body_id: hir::BodyId, span: Span, id: ast::NodeId) { let (is_item_fn, is_unsafe_fn) = match fn_kind { FnKind::ItemFn(_, _, unsafety, ..) => diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index b3e61f1e570..1efc4b37ed5 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -289,9 +289,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { pub fn walk_fn(&mut self, decl: &hir::FnDecl, - body: &hir::Expr) { - self.walk_arg_patterns(decl, body); - self.consume_expr(body); + body: &hir::Body) { + self.walk_arg_patterns(decl, &body.value); + self.consume_expr(&body.value); } fn walk_arg_patterns(&mut self, @@ -537,9 +537,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { } } - hir::ExprRepeat(ref base, ref count) => { + hir::ExprRepeat(ref base, _) => { self.consume_expr(&base); - self.consume_expr(&count); } hir::ExprClosure(.., fn_decl_span) => { diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 1c31e1800ee..d932061d42d 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -34,13 +34,13 @@ struct ItemVisitor<'a, 'tcx: 'a> { } impl<'a, 'tcx> ItemVisitor<'a, 'tcx> { - fn visit_const(&mut self, item_id: ast::NodeId, expr: &'tcx hir::Expr) { + fn visit_const(&mut self, item_id: ast::NodeId, body: hir::BodyId) { let param_env = ty::ParameterEnvironment::for_item(self.tcx, item_id); self.tcx.infer_ctxt(None, Some(param_env), Reveal::All).enter(|infcx| { let mut visitor = ExprVisitor { infcx: &infcx }; - visitor.visit_expr(expr); + visitor.visit_nested_body(body); }); } } @@ -122,33 +122,33 @@ impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> { } // const, static and N in [T; N]. - fn visit_expr(&mut self, expr: &'tcx hir::Expr) { + fn visit_body(&mut self, body: &'tcx hir::Body) { self.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| { let mut visitor = ExprVisitor { infcx: &infcx }; - visitor.visit_expr(expr); + visitor.visit_body(body); }); } fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) { - if let hir::TraitItemKind::Const(_, Some(ref expr)) = item.node { - self.visit_const(item.id, expr); + if let hir::TraitItemKind::Const(_, Some(body)) = item.node { + self.visit_const(item.id, body); } else { intravisit::walk_trait_item(self, item); } } fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) { - if let hir::ImplItemKind::Const(_, ref expr) = item.node { - self.visit_const(item.id, expr); + if let hir::ImplItemKind::Const(_, body) = item.node { + self.visit_const(item.id, body); } else { intravisit::walk_impl_item(self, item); } } fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, - b: hir::ExprId, s: Span, id: ast::NodeId) { + b: hir::BodyId, s: Span, id: ast::NodeId) { if let FnKind::Closure(..) = fk { span_bug!(s, "intrinsicck: closure outside of function") } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 445aed8f97d..ea1c897708b 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -188,7 +188,7 @@ impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> { } fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, - b: hir::ExprId, s: Span, id: NodeId) { + b: hir::BodyId, s: Span, id: NodeId) { visit_fn(self, fk, fd, b, s, id); } fn visit_local(&mut self, l: &'tcx hir::Local) { visit_local(self, l); } @@ -354,13 +354,9 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.ir.tcx.map) + NestedVisitorMap::None } - fn visit_fn(&mut self, _: FnKind<'tcx>, _: &'tcx hir::FnDecl, - _: hir::ExprId, _: Span, _: NodeId) { - // do not check contents of nested fns - } fn visit_local(&mut self, l: &'tcx hir::Local) { check_local(self, l); } @@ -375,7 +371,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> { fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>, fk: FnKind<'tcx>, decl: &'tcx hir::FnDecl, - body_id: hir::ExprId, + body_id: hir::BodyId, sp: Span, id: ast::NodeId) { debug!("visit_fn"); @@ -408,14 +404,14 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>, clean_exit_var: fn_maps.add_variable(CleanExit) }; - let body = ir.tcx.map.expr(body_id); + 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); + let entry_ln = lsets.compute(&body.value); // check for various error conditions - lsets.visit_expr(body); + lsets.visit_body(body); lsets.check_ret(id, sp, fk, entry_ln, body); lsets.warn_about_unused_args(decl, entry_ln); } @@ -942,7 +938,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { loop. The next-node for a continue is the top of this loop. */ let node = self.live_node(expr.id, expr.span); - self.with_loop_nodes(blk_id.node_id(), succ, node, |this| { + self.with_loop_nodes(blk_id.node_id, succ, node, |this| { // the construction of a closure itself is not important, // but we have to consider the closed over variables. @@ -1088,11 +1084,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_exprs(exprs, succ) } - hir::ExprRepeat(ref element, ref count) => { - let succ = self.propagate_through_expr(&count, succ); - self.propagate_through_expr(&element, succ) - } - hir::ExprStruct(_, ref fields, ref with_expr) => { let succ = self.propagate_through_opt_expr(with_expr.as_ref().map(|e| &**e), succ); fields.iter().rev().fold(succ, |succ, field| { @@ -1149,7 +1140,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprAddrOf(_, ref e) | hir::ExprCast(ref e, _) | hir::ExprType(ref e, _) | - hir::ExprUnary(_, ref e) => { + hir::ExprUnary(_, ref e) | + hir::ExprRepeat(ref e, _) => { self.propagate_through_expr(&e, succ) } @@ -1443,7 +1435,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { sp: Span, fk: FnKind, entry_ln: LiveNode, - body: &hir::Expr) + body: &hir::Body) { let fn_ty = if let FnKind::Closure(_) = fk { self.ir.tcx.tables().node_id_to_type(id) @@ -1460,7 +1452,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // and must outlive the *call-site* of the function. let fn_ret = self.ir.tcx.liberate_late_bound_regions( - self.ir.tcx.region_maps.call_site_extent(id, body.id), + self.ir.tcx.region_maps.call_site_extent(id, body.value.id), &fn_ret); if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 4c3b102e540..fdc5087ce9b 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -705,7 +705,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { }; match fn_expr.node { - hir::ExprClosure(.., body_id, _) => body_id.node_id(), + hir::ExprClosure(.., body_id, _) => body_id.node_id, _ => bug!() } }; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 25f70d04819..34a42dede75 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -250,15 +250,15 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { match item.node { hir::ItemFn(.., body) => { if item_might_be_inlined(&item) { - self.visit_body(body); + self.visit_nested_body(body); } } // Reachable constants will be inlined into other crates // unconditionally, so we need to make sure that their // contents are also reachable. - hir::ItemConst(_, ref init) => { - self.visit_expr(&init); + hir::ItemConst(_, init) => { + self.visit_nested_body(init); } // These are normal, nothing reachable about these @@ -278,24 +278,22 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { hir::TraitItemKind::Method(_, None) => { // Keep going, nothing to get exported } - hir::TraitItemKind::Const(_, Some(ref body)) => { - self.visit_expr(body); - } + hir::TraitItemKind::Const(_, Some(body_id)) | hir::TraitItemKind::Method(_, Some(body_id)) => { - self.visit_body(body_id); + self.visit_nested_body(body_id); } hir::TraitItemKind::Type(..) => {} } } ast_map::NodeImplItem(impl_item) => { match impl_item.node { - hir::ImplItemKind::Const(_, ref expr) => { - self.visit_expr(&expr); + hir::ImplItemKind::Const(_, body) => { + self.visit_nested_body(body); } hir::ImplItemKind::Method(ref sig, body) => { let did = self.tcx.map.get_parent_did(search_item); if method_might_be_inlined(self.tcx, sig, impl_item, did) { - self.visit_body(body) + self.visit_nested_body(body) } } hir::ImplItemKind::Type(_) => {} diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index b1e35e54eb9..faf4a448b7a 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -1088,7 +1088,7 @@ fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'tcx, 'a fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, kind: FnKind<'tcx>, decl: &'tcx hir::FnDecl, - body_id: hir::ExprId, + body_id: hir::BodyId, sp: Span, id: ast::NodeId) { debug!("region::resolve_fn(id={:?}, \ @@ -1101,22 +1101,22 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, visitor.cx.parent); visitor.cx.parent = visitor.new_code_extent( - CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id() }); + CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id }); let fn_decl_scope = visitor.new_code_extent( - CodeExtentData::ParameterScope { fn_id: id, body_id: body_id.node_id() }); + CodeExtentData::ParameterScope { fn_id: id, body_id: body_id.node_id }); if let Some(root_id) = visitor.cx.root_id { - visitor.region_maps.record_fn_parent(body_id.node_id(), root_id); + visitor.region_maps.record_fn_parent(body_id.node_id, root_id); } let outer_cx = visitor.cx; let outer_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet()); - visitor.terminating_scopes.insert(body_id.node_id()); + visitor.terminating_scopes.insert(body_id.node_id); // The arguments and `self` are parented to the fn. visitor.cx = Context { - root_id: Some(body_id.node_id()), + root_id: Some(body_id.node_id), parent: ROOT_CODE_EXTENT, var_parent: fn_decl_scope, }; @@ -1126,11 +1126,11 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, // The body of the every fn is a root scope. visitor.cx = Context { - root_id: Some(body_id.node_id()), + root_id: Some(body_id.node_id), parent: fn_decl_scope, var_parent: fn_decl_scope }; - visitor.visit_body(body_id); + visitor.visit_nested_body(body_id); // Restore context we had at the start. visitor.cx = outer_cx; @@ -1195,7 +1195,7 @@ impl<'ast, 'a> Visitor<'ast> for RegionResolutionVisitor<'ast, 'a> { } fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl, - b: hir::ExprId, s: Span, n: NodeId) { + b: hir::BodyId, s: Span, n: NodeId) { resolve_fn(self, fk, fd, b, s, n); } fn visit_arm(&mut self, a: &'ast Arm) { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 443770e61b6..9b70c522362 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -206,7 +206,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } fn visit_fn(&mut self, fk: FnKind<'tcx>, decl: &'tcx hir::FnDecl, - b: hir::ExprId, s: Span, fn_id: ast::NodeId) { + b: hir::BodyId, s: Span, fn_id: ast::NodeId) { match fk { FnKind::ItemFn(_, generics, ..) => { self.visit_early_late(fn_id,decl, generics, |this| { @@ -407,7 +407,7 @@ fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, sha // Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning // if one of the label shadows a lifetime or another label. -fn extract_labels(ctxt: &mut LifetimeContext, b: hir::ExprId) { +fn extract_labels(ctxt: &mut LifetimeContext, b: hir::BodyId) { struct GatherLabels<'a> { sess: &'a Session, scope: Scope<'a>, @@ -419,7 +419,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: hir::ExprId) { scope: ctxt.scope, labels_in_fn: &mut ctxt.labels_in_fn, }; - gather.visit_expr(ctxt.hir_map.expr(b)); + gather.visit_body(ctxt.hir_map.body(b)); return; impl<'v, 'a> Visitor<'v> for GatherLabels<'a> { @@ -501,7 +501,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { fn add_scope_and_walk_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, - fb: hir::ExprId, + fb: hir::BodyId, _span: Span, fn_id: ast::NodeId) { match fk { @@ -522,8 +522,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // `self.labels_in_fn`. extract_labels(self, fb); - self.with(FnScope { fn_id: fn_id, body_id: fb.node_id(), s: self.scope }, - |_old_scope, this| this.visit_body(fb)) + self.with(FnScope { fn_id: fn_id, body_id: fb.node_id, s: self.scope }, + |_old_scope, this| this.visit_nested_body(fb)) } // FIXME(#37666) this works around a limitation in the region inferencer diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 67137470098..28192cd1873 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1206,7 +1206,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( impl_item.span, tcx.map.local_def_id(id), - tcx.region_maps.call_site_extent(id, body.node_id())) + tcx.region_maps.call_site_extent(id, body.node_id)) } } } @@ -1227,7 +1227,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { // to the method id). let extent = if let Some(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()) + tcx.region_maps.call_site_extent(id, body_id.node_id) } else { // no default impl: use item extent as free_id_outlive bound. tcx.region_maps.item_extent(id) @@ -1248,7 +1248,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( item.span, fn_def_id, - tcx.region_maps.call_site_extent(id, body_id.node_id())) + tcx.region_maps.call_site_extent(id, body_id.node_id)) } hir::ItemEnum(..) | hir::ItemStruct(..) | @@ -1284,7 +1284,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( expr.span, base_def_id, - tcx.region_maps.call_site_extent(id, body.node_id())) + tcx.region_maps.call_site_extent(id, body.node_id)) } else { tcx.empty_parameter_environment() } diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 5ed628d7dca..e5b764be879 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -190,8 +190,8 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, all_loans: &[Loan<'tcx>], fn_id: ast::NodeId, decl: &hir::FnDecl, - body: &hir::Expr) { - debug!("check_loans(body id={})", body.id); + body: &hir::Body) { + debug!("check_loans(body id={})", body.value.id); let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id); let infcx = bccx.tcx.borrowck_fake_infer_ctxt(param_env); diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 5d59b58b847..50b276ce694 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -42,13 +42,13 @@ mod move_error; pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, fn_id: NodeId, decl: &hir::FnDecl, - body: &hir::Expr) + body: &hir::Body) -> (Vec>, move_data::MoveData<'tcx>) { let mut glcx = GatherLoanCtxt { bccx: bccx, all_loans: Vec::new(), - item_ub: bccx.tcx.region_maps.node_extent(body.id), + item_ub: bccx.tcx.region_maps.node_extent(body.value.id), move_data: MoveData::new(), move_error_collector: move_error::MoveErrorCollector::new(), }; @@ -548,14 +548,14 @@ impl<'a, 'tcx> Visitor<'tcx> for StaticInitializerCtxt<'a, 'tcx> { pub fn gather_loans_in_static_initializer<'a, 'tcx>(bccx: &mut BorrowckCtxt<'a, 'tcx>, item_id: ast::NodeId, - expr: &'tcx hir::Expr) { + body: hir::BodyId) { - debug!("gather_loans_in_static_initializer(expr={:?})", expr); + debug!("gather_loans_in_static_initializer(expr={:?})", body); let mut sicx = StaticInitializerCtxt { bccx: bccx, item_id: item_id }; - sicx.visit_expr(expr); + sicx.visit_nested_body(body); } diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index 9035c2ab3c2..c3ff564121c 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -11,10 +11,7 @@ use borrowck::BorrowckCtxt; use syntax::ast::{self, MetaItem}; -use syntax_pos::{Span, DUMMY_SP}; - -use rustc::hir; -use rustc::hir::intravisit::{FnKind}; +use syntax_pos::DUMMY_SP; use rustc::mir::{self, BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location}; use rustc::session::Session; @@ -55,27 +52,14 @@ pub struct MoveDataParamEnv<'tcx> { } pub fn borrowck_mir(bcx: &mut BorrowckCtxt, - fk: FnKind, - _decl: &hir::FnDecl, - body: &hir::Expr, - _sp: Span, id: ast::NodeId, attributes: &[ast::Attribute]) { - match fk { - FnKind::ItemFn(name, ..) | - FnKind::Method(name, ..) => { - debug!("borrowck_mir({}) UNIMPLEMENTED", name); - } - FnKind::Closure(_) => { - debug!("borrowck_mir closure (body.id={}) UNIMPLEMENTED", body.id); - } - } - let tcx = bcx.tcx; + let def_id = tcx.map.local_def_id(id); + debug!("borrowck_mir({}) UNIMPLEMENTED", tcx.item_path_str(def_id)); + + let mir = &tcx.item_mir(def_id); let param_env = ty::ParameterEnvironment::for_item(tcx, id); - - let mir = &tcx.item_mir(tcx.map.local_def_id(id)); - let move_data = MoveData::gather_moves(mir, tcx, ¶m_env); let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env }; let flow_inits = diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index ebbd1baa8fa..93c12fed1de 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -68,7 +68,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BorrowckCtxt<'a, 'tcx> { } fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, - b: hir::ExprId, s: Span, id: ast::NodeId) { + b: hir::BodyId, s: Span, id: ast::NodeId) { match fk { FnKind::ItemFn(..) | FnKind::Method(..) => { @@ -88,15 +88,15 @@ impl<'a, 'tcx> Visitor<'tcx> for BorrowckCtxt<'a, 'tcx> { } fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) { - if let hir::TraitItemKind::Const(_, Some(ref expr)) = ti.node { - gather_loans::gather_loans_in_static_initializer(self, ti.id, &expr); + if let hir::TraitItemKind::Const(_, Some(expr)) = ti.node { + gather_loans::gather_loans_in_static_initializer(self, ti.id, expr); } intravisit::walk_trait_item(self, ti); } fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { - if let hir::ImplItemKind::Const(_, ref expr) = ii.node { - gather_loans::gather_loans_in_static_initializer(self, ii.id, &expr); + if let hir::ImplItemKind::Const(_, expr) = ii.node { + gather_loans::gather_loans_in_static_initializer(self, ii.id, expr); } intravisit::walk_impl_item(self, ii); } @@ -141,9 +141,9 @@ fn borrowck_item<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, item: &'tcx hir::I // loan step is intended for things that have a data // flow dependent conditions. match item.node { - hir::ItemStatic(.., ref ex) | - hir::ItemConst(_, ref ex) => { - gather_loans::gather_loans_in_static_initializer(this, item.id, &ex); + hir::ItemStatic(.., ex) | + hir::ItemConst(_, ex) => { + gather_loans::gather_loans_in_static_initializer(this, item.id, ex); } _ => { } } @@ -161,21 +161,21 @@ pub struct AnalysisData<'a, 'tcx: 'a> { fn borrowck_fn<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, fk: FnKind<'tcx>, decl: &'tcx hir::FnDecl, - body_id: hir::ExprId, + body_id: hir::BodyId, sp: Span, id: ast::NodeId, attributes: &[ast::Attribute]) { debug!("borrowck_fn(id={})", id); - let body = this.tcx.map.expr(body_id); + let body = this.tcx.map.body(body_id); if attributes.iter().any(|item| item.check_name("rustc_mir_borrowck")) { this.with_temp_region_map(id, |this| { - mir::borrowck_mir(this, fk, decl, body, sp, id, attributes) + mir::borrowck_mir(this, id, attributes) }); } - let cfg = cfg::CFG::new(this.tcx, body); + let cfg = cfg::CFG::new(this.tcx, &body.value); let AnalysisData { all_loans, loans: loan_dfcx, move_data: flowed_moves } = @@ -204,14 +204,14 @@ 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::Expr, + 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, sp, id, &tcx.map); + let id_range = intravisit::compute_id_range_for_fn_body(fk, decl, body.id(), sp, id, &tcx.map); let (all_loans, move_data) = gather_loans::gather_loans_in_fn(this, id, decl, body); @@ -263,7 +263,7 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>( } }; - let body = tcx.map.expr(fn_parts.body); + let body = tcx.map.body(fn_parts.body); let dataflow_data = build_borrowck_dataflow_data(&mut bccx, fn_parts.kind, @@ -416,7 +416,7 @@ pub fn closure_to_block(closure_id: ast::NodeId, match tcx.map.get(closure_id) { hir_map::NodeExpr(expr) => match expr.node { hir::ExprClosure(.., body_id, _) => { - body_id.node_id() + body_id.node_id } _ => { bug!("encountered non-closure id: {}", closure_id) diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index 32bda5e1162..6a5ee13bb84 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -656,7 +656,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { cfg: &cfg::CFG, id_range: IdRange, decl: &hir::FnDecl, - body: &hir::Expr) + body: &hir::Body) -> FlowedMoveData<'a, 'tcx> { let mut dfcx_moves = DataFlowContext::new(tcx, diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index da28187496b..cb1d67d01c7 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -67,7 +67,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { } fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, - b: hir::ExprId, s: Span, id: ast::NodeId) { + b: hir::BodyId, s: Span, id: ast::NodeId) { if let FnKind::Closure(..) = fk { span_bug!(s, "check_match: closure outside of function") } @@ -120,7 +120,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> { } fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, - b: hir::ExprId, s: Span, n: ast::NodeId) { + b: hir::BodyId, s: Span, n: ast::NodeId) { intravisit::walk_fn(self, fk, fd, b, s, n); for input in &fd.inputs { diff --git a/src/librustc_const_eval/diagnostics.rs b/src/librustc_const_eval/diagnostics.rs index 83b0d9dec6d..b24cd261dd5 100644 --- a/src/librustc_const_eval/diagnostics.rs +++ b/src/librustc_const_eval/diagnostics.rs @@ -576,18 +576,18 @@ https://doc.rust-lang.org/reference.html#ffi-attributes E0306: r##" -In an array literal `[x; N]`, `N` is the number of elements in the array. This +In an array type `[T; N]`, `N` is the number of elements in the array. This must be an unsigned integer. Erroneous code example: ```compile_fail,E0306 -let x = [0i32; true]; // error: expected positive integer for repeat count, - // found boolean +const X: [i32; true] = [0]; // error: expected `usize` for array length, + // found boolean ``` Working example: ``` -let x = [0i32; 2]; +const X: [i32; 1] = [0]; ``` "##, } diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 09f38e5be8f..c42b558830f 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -56,15 +56,17 @@ macro_rules! math { fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, variant_def: DefId) -> Option<&'tcx Expr> { - fn variant_expr<'a>(variants: &'a [hir::Variant], id: ast::NodeId) - -> Option<&'a Expr> { + let variant_expr = |variants: &'tcx [hir::Variant], id: ast::NodeId | + -> Option<&'tcx Expr> { for variant in variants { if variant.node.data.id() == id { - return variant.node.disr_expr.as_ref().map(|e| &**e); + return variant.node.disr_expr.map(|e| { + &tcx.map.body(e).value + }); } } None - } + }; if let Some(variant_node_id) = tcx.map.as_local_node_id(variant_def) { let enum_node_id = tcx.map.get_parent(variant_node_id); @@ -96,21 +98,24 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match tcx.map.find(node_id) { None => None, Some(ast_map::NodeItem(it)) => match it.node { - hir::ItemConst(ref ty, ref const_expr) => { - Some((&const_expr, tcx.ast_ty_to_prim_ty(ty))) + hir::ItemConst(ref ty, body) => { + Some((&tcx.map.body(body).value, + tcx.ast_ty_to_prim_ty(ty))) } _ => None }, Some(ast_map::NodeTraitItem(ti)) => match ti.node { - hir::TraitItemKind::Const(ref ty, ref expr_option) => { + hir::TraitItemKind::Const(ref ty, default) => { if let Some(substs) = substs { // If we have a trait item and the substitutions for it, // `resolve_trait_associated_const` will select an impl // or the default. let trait_id = tcx.map.get_parent(node_id); let trait_id = tcx.map.local_def_id(trait_id); - let default_value = expr_option.as_ref() - .map(|expr| (&**expr, tcx.ast_ty_to_prim_ty(ty))); + let default_value = default.map(|body| { + (&tcx.map.body(body).value, + tcx.ast_ty_to_prim_ty(ty)) + }); resolve_trait_associated_const(tcx, def_id, default_value, trait_id, substs) } else { // Technically, without knowing anything about the @@ -125,8 +130,9 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, _ => None }, Some(ast_map::NodeImplItem(ii)) => match ii.node { - hir::ImplItemKind::Const(ref ty, ref expr) => { - Some((&expr, tcx.ast_ty_to_prim_ty(ty))) + hir::ImplItemKind::Const(ref ty, body) => { + Some((&tcx.map.body(body).value, + tcx.ast_ty_to_prim_ty(ty))) } _ => None }, @@ -142,8 +148,8 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let mut used_substs = false; let expr_ty = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) { - Some((&InlinedItem { body: ref const_expr, .. }, _)) => { - Some((&**const_expr, Some(tcx.sess.cstore.item_type(tcx, def_id)))) + Some((&InlinedItem { ref body, .. }, _)) => { + Some((&body.value, Some(tcx.sess.cstore.item_type(tcx, def_id)))) } _ => None }; @@ -864,18 +870,18 @@ 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_id) = match lookup_const_fn_by_id(tcx, did) { - Some(ConstFnNode::Inlined(ii)) => (ii.const_fn_args.clone(), ii.body.expr_id()), + 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(), - fn_like.body()), + tcx.map.body(fn_like.body())), None => signal!(e, NonConstPath), }; - let result = tcx.map.expr(body_id); + let result = &body.value; assert_eq!(arg_defs.len(), args.len()); let mut call_args = DefIdMap(); @@ -893,7 +899,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, result, ty_hint, Some(&call_args))? }, hir::ExprLit(ref lit) => match lit_to_const(&lit.node, tcx, ety) { Ok(val) => val, @@ -953,11 +959,12 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } hir::ExprArray(ref v) => Array(e.id, v.len() as u64), - hir::ExprRepeat(_, ref n) => { + hir::ExprRepeat(_, n) => { let len_hint = ty_hint.checked_or(tcx.types.usize); + let n = &tcx.map.body(n).value; Repeat( e.id, - match eval_const_expr_partial(tcx, &n, len_hint, fn_args)? { + match eval_const_expr_partial(tcx, n, len_hint, fn_args)? { Integral(Usize(i)) => i.as_u64(tcx.sess.target.uint_type), Integral(_) => signal!(e, RepeatCountNotNatural), _ => signal!(e, RepeatCountNotInt), diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 74df1e52bde..8e77beea8e4 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -702,8 +702,8 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec, let cfg = match code { blocks::Code::Expr(expr) => cfg::CFG::new(tcx, expr), blocks::Code::FnLike(fn_like) => { - let body = tcx.map.expr(fn_like.body()); - cfg::CFG::new(tcx, body) + let body = tcx.map.body(fn_like.body()); + cfg::CFG::new(tcx, &body.value) }, }; let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges; diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index 173bcdc5b7a..11ade150d1c 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -188,7 +188,7 @@ enum SawAbiComponent<'a> { SawTraitItem(SawTraitOrImplItemComponent), SawImplItem(SawTraitOrImplItemComponent), SawStructField, - SawVariant, + SawVariant(bool), SawQPath, SawPathSegment, SawPathParameters, @@ -584,7 +584,7 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has g: &'tcx Generics, item_id: NodeId) { debug!("visit_variant: st={:?}", self.st); - SawVariant.hash(self.st); + SawVariant(v.node.disr_expr.is_some()).hash(self.st); hash_attrs!(self, &v.node.attrs); visit::walk_variant(self, v, g, item_id) } @@ -616,7 +616,12 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has // implicitly hashing the discriminant of SawExprComponent. hash_span!(self, ex.span, force_span); hash_attrs!(self, &ex.attrs); - visit::walk_expr(self, ex) + + // Always hash nested constant bodies (e.g. n in `[x; n]`). + let hash_bodies = self.hash_bodies; + self.hash_bodies = true; + visit::walk_expr(self, ex); + self.hash_bodies = hash_bodies; } fn visit_stmt(&mut self, s: &'tcx Stmt) { @@ -686,7 +691,12 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has debug!("visit_ty: st={:?}", self.st); SawTy(saw_ty(&t.node)).hash(self.st); hash_span!(self, t.span); - visit::walk_ty(self, t) + + // Always hash nested constant bodies (e.g. N in `[T; N]`). + let hash_bodies = self.hash_bodies; + self.hash_bodies = true; + visit::walk_ty(self, t); + self.hash_bodies = hash_bodies; } fn visit_generics(&mut self, g: &'tcx Generics) { @@ -1159,7 +1169,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { items: _, trait_items: _, impl_items: _, - exprs: _, + bodies: _, } = *krate; visit::Visitor::visit_mod(self, module, span, ast::CRATE_NODE_ID); diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index 4be6058ec2f..5354233e57c 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -243,7 +243,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { cx: &LateContext, fk: FnKind, _: &hir::FnDecl, - _: &hir::Expr, + _: &hir::Body, span: Span, id: ast::NodeId) { match fk { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 0fb5dbf0ad2..501da680728 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -222,7 +222,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode { cx: &LateContext, fk: FnKind<'tcx>, _: &hir::FnDecl, - _: &hir::Expr, + _: &hir::Body, span: Span, _: ast::NodeId) { match fk { @@ -674,7 +674,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { cx: &LateContext, fn_kind: FnKind, _: &hir::FnDecl, - blk: &hir::Expr, + body: &hir::Body, sp: Span, id: ast::NodeId) { let method = match fn_kind { @@ -712,7 +712,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { // to have behaviour like the above, rather than // e.g. accidentally recurring after an assert. - let cfg = cfg::CFG::new(cx.tcx, blk); + let cfg = cfg::CFG::new(cx.tcx, &body.value); let mut work_queue = vec![cfg.entry]; let mut reached_exit_without_self_call = false; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 429bfb8e3d6..b4c9a0672b0 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -98,7 +98,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedMut { cx: &LateContext, _: FnKind, decl: &hir::FnDecl, - _: &hir::Expr, + _: &hir::Body, _: Span, _: ast::NodeId) { for a in &decl.inputs { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 0ac3ffd5cb9..6132b23c720 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -485,7 +485,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { .insert(def_id, None); } Some(&InlinedItem { ref body, .. }) => { - let inlined_root_node_id = find_inlined_item_root(body.id); + let inlined_root_node_id = find_inlined_item_root(body.value.id); cache_inlined_item(def_id, inlined_root_node_id, inlined_root_node_id); } } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 72abf3ea36a..1c4225817a9 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -802,7 +802,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { _ => None, }, mir: match item.node { - hir::ItemStatic(..) | + hir::ItemStatic(..) if self.tcx.sess.opts.debugging_opts.always_encode_mir => { + self.encode_mir(def_id) + } hir::ItemConst(..) => self.encode_mir(def_id), hir::ItemFn(_, _, constness, _, ref generics, _) => { let tps_len = generics.ty_params.len(); diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 0e4dbb04777..7eefcdb15d0 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -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>, - ast_body: &'gcx hir::Expr) + body_id: hir::BodyId) -> Mir<'tcx> where A: Iterator, Option<&'gcx hir::Pat>)> { @@ -136,17 +136,17 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, let span = tcx.map.span(fn_id); let mut builder = Builder::new(hir, span, arguments.len(), return_ty); - let body_id = ast_body.id; let call_site_extent = tcx.region_maps.lookup_code_extent( - CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id }); + CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id.node_id }); let arg_extent = tcx.region_maps.lookup_code_extent( - CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body_id }); + CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body_id.node_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| { - builder.args_and_body(block, &arguments, arg_extent, ast_body) + let ast_expr = &tcx.map.body(body_id).value; + builder.args_and_body(block, &arguments, arg_extent, ast_expr) })); // Attribute epilogue to function's closing brace let fn_end = Span { lo: span.hi, ..span }; @@ -197,9 +197,10 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>, item_id: ast::NodeId, - ast_expr: &'tcx hir::Expr) + body_id: hir::BodyId) -> Mir<'tcx> { let tcx = hir.tcx(); + let ast_expr = &tcx.map.body(body_id).value; let ty = tcx.tables().expr_ty_adjusted(ast_expr); let span = tcx.map.span(item_id); let mut builder = Builder::new(hir, span, 0, ty); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index d579cdb042f..cc65fdede09 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -575,7 +575,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } // Now comes the rote stuff: - hir::ExprRepeat(ref v, ref c) => { + hir::ExprRepeat(ref v, c) => { + let c = &cx.tcx.map.body(c).value; ExprKind::Repeat { value: v.to_ref(), count: TypedConstVal { @@ -585,7 +586,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ConstVal::Integral(ConstInt::Usize(u)) => u, other => bug!("constant evaluation of repeat count yielded {:?}", other), }, - }, + } } } hir::ExprRet(ref v) => ExprKind::Return { value: v.to_ref() }, @@ -780,7 +781,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let body_id = match cx.tcx.map.find(closure_expr_id) { Some(map::NodeExpr(expr)) => { match expr.node { - hir::ExprClosure(.., body_id, _) => body_id.node_id(), + hir::ExprClosure(.., body, _) => body.node_id, _ => { span_bug!(expr.span, "closure expr is not a closure expr"); } diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index 403b84c7584..607411684e7 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -129,16 +129,17 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> { } impl<'a, 'gcx> BuildMir<'a, 'gcx> { - fn build_const_integer(&mut self, expr: &'gcx hir::Expr) { + fn build_const_integer(&mut self, body: hir::BodyId) { + let body = self.tcx.map.body(body); // FIXME(eddyb) Closures should have separate // function definition IDs and expression IDs. // Type-checking should not let closures get // this far in an integer constant position. - if let hir::ExprClosure(..) = expr.node { + if let hir::ExprClosure(..) = body.value.node { return; } - self.cx(MirSource::Const(expr.id)).build(|cx| { - build::construct_const(cx, expr.id, expr) + self.cx(MirSource::Const(body.value.id)).build(|cx| { + build::construct_const(cx, body.value.id, body.id()) }); } } @@ -151,12 +152,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { // Const and static items. fn visit_item(&mut self, item: &'tcx hir::Item) { match item.node { - hir::ItemConst(_, ref expr) => { + hir::ItemConst(_, expr) => { self.cx(MirSource::Const(item.id)).build(|cx| { build::construct_const(cx, item.id, expr) }); } - hir::ItemStatic(_, m, ref expr) => { + hir::ItemStatic(_, m, expr) => { self.cx(MirSource::Static(item.id, m)).build(|cx| { build::construct_const(cx, item.id, expr) }); @@ -168,7 +169,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { // Trait associated const defaults. fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) { - if let hir::TraitItemKind::Const(_, Some(ref expr)) = item.node { + if let hir::TraitItemKind::Const(_, Some(expr)) = item.node { self.cx(MirSource::Const(item.id)).build(|cx| { build::construct_const(cx, item.id, expr) }); @@ -178,7 +179,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { // Impl associated const. fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) { - if let hir::ImplItemKind::Const(_, ref expr) = item.node { + if let hir::ImplItemKind::Const(_, expr) = item.node { self.cx(MirSource::Const(item.id)).build(|cx| { build::construct_const(cx, item.id, expr) }); @@ -188,7 +189,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { // Repeat counts, i.e. [expr; constant]. fn visit_expr(&mut self, expr: &'tcx hir::Expr) { - if let hir::ExprRepeat(_, ref count) = expr.node { + if let hir::ExprRepeat(_, count) = expr.node { self.build_const_integer(count); } intravisit::walk_expr(self, expr); @@ -196,7 +197,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { // Array lengths, i.e. [T; constant]. fn visit_ty(&mut self, ty: &'tcx hir::Ty) { - if let hir::TyArray(_, ref length) = ty.node { + if let hir::TyArray(_, length) = ty.node { self.build_const_integer(length); } intravisit::walk_ty(self, ty); @@ -205,7 +206,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { // Enum variant discriminant values. fn visit_variant(&mut self, v: &'tcx hir::Variant, g: &'tcx hir::Generics, item_id: ast::NodeId) { - if let Some(ref expr) = v.node.disr_expr { + if let Some(expr) = v.node.disr_expr { self.build_const_integer(expr); } intravisit::walk_variant(self, v, g, item_id); @@ -214,7 +215,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { fn visit_fn(&mut self, fk: FnKind<'tcx>, decl: &'tcx hir::FnDecl, - body_id: hir::ExprId, + body_id: hir::BodyId, span: Span, id: ast::NodeId) { // fetch the fully liberated fn signature (that is, all bound @@ -227,7 +228,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { }; let (abi, implicit_argument) = if let FnKind::Closure(..) = fk { - (Abi::Rust, Some((closure_self_ty(self.tcx, id, body_id.node_id()), None))) + (Abi::Rust, Some((closure_self_ty(self.tcx, id, body_id.node_id), None))) } else { let def_id = self.tcx.map.local_def_id(id); (self.tcx.item_type(def_id).fn_abi(), None) @@ -241,11 +242,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { (fn_sig.inputs()[index], Some(&*arg.pat)) }); - let body = self.tcx.map.expr(body_id); - 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) + build::construct_fn(cx, id, arguments, abi, fn_sig.output(), body_id) }); intravisit::walk_fn(self, fk, decl, body_id, span, id); diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 2ea5c6d8c47..10983aab309 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -100,6 +100,11 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { .enter(|infcx| f(&mut euv::ExprUseVisitor::new(self, &infcx))) } + fn global_body(&mut self, mode: Mode, body: hir::BodyId) -> ConstQualif { + let expr = &self.tcx.map.body(body).value; + self.global_expr(mode, expr) + } + fn global_expr(&mut self, mode: Mode, expr: &'gcx hir::Expr) -> ConstQualif { assert!(mode != Mode::Var); match self.tcx.const_qualif_map.borrow_mut().entry(expr.id) { @@ -134,7 +139,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { fn fn_like(&mut self, fk: FnKind<'gcx>, fd: &'gcx hir::FnDecl, - b: hir::ExprId, + b: hir::BodyId, s: Span, fn_id: ast::NodeId) -> ConstQualif { @@ -160,7 +165,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { }; let qualif = self.with_mode(mode, |this| { - let body = this.tcx.map.expr(b); + let body = this.tcx.map.body(b); this.with_euv(Some(fn_id), |euv| euv.walk_fn(fd, body)); intravisit::walk_fn(this, fk, fd, b, s, fn_id); this.qualif @@ -197,7 +202,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { true }, Some(ConstFnNode::Inlined(ii)) => { - let node_id = ii.body.id; + let node_id = ii.body.value.id; let qualif = match self.tcx.const_qualif_map.borrow_mut().entry(node_id) { Entry::Occupied(entry) => *entry.get(), @@ -241,19 +246,19 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { debug!("visit_item(item={})", self.tcx.map.node_to_string(i.id)); assert_eq!(self.mode, Mode::Var); match i.node { - hir::ItemStatic(_, hir::MutImmutable, ref expr) => { - self.global_expr(Mode::Static, &expr); + hir::ItemStatic(_, hir::MutImmutable, expr) => { + self.global_body(Mode::Static, expr); } - hir::ItemStatic(_, hir::MutMutable, ref expr) => { - self.global_expr(Mode::StaticMut, &expr); + hir::ItemStatic(_, hir::MutMutable, expr) => { + self.global_body(Mode::StaticMut, expr); } - hir::ItemConst(_, ref expr) => { - self.global_expr(Mode::Const, &expr); + hir::ItemConst(_, expr) => { + self.global_body(Mode::Const, expr); } hir::ItemEnum(ref enum_definition, _) => { for var in &enum_definition.variants { - if let Some(ref ex) = var.node.disr_expr { - self.global_expr(Mode::Const, &ex); + if let Some(ex) = var.node.disr_expr { + self.global_body(Mode::Const, ex); } } } @@ -265,9 +270,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { fn visit_trait_item(&mut self, t: &'tcx hir::TraitItem) { match t.node { - hir::TraitItemKind::Const(_, ref default) => { - if let Some(ref expr) = *default { - self.global_expr(Mode::Const, &expr); + hir::TraitItemKind::Const(_, default) => { + if let Some(expr) = default { + self.global_body(Mode::Const, expr); } else { intravisit::walk_trait_item(self, t); } @@ -278,8 +283,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) { match i.node { - hir::ImplItemKind::Const(_, ref expr) => { - self.global_expr(Mode::Const, &expr); + hir::ImplItemKind::Const(_, expr) => { + self.global_body(Mode::Const, expr); } _ => self.with_mode(Mode::Var, |v| intravisit::walk_impl_item(v, i)), } @@ -288,7 +293,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, - b: hir::ExprId, + b: hir::BodyId, s: Span, fn_id: ast::NodeId) { self.fn_like(fk, fd, b, s, fn_id); diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index 34b6c5e7571..65a60732fc8 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -177,7 +177,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { fn visit_fn(&mut self, fk: hir_visit::FnKind<'v>, fd: &'v hir::FnDecl, - b: hir::ExprId, + b: hir::BodyId, s: Span, id: NodeId) { self.record("FnDecl", Id::None, fd); diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 10f464a9901..df9fe00e9a8 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -84,7 +84,7 @@ impl<'a, 'ast> Visitor<'ast> for CheckLoopVisitor<'a, 'ast> { self.with_context(Loop(LoopKind::Loop(source)), |v| v.visit_block(&b)); } hir::ExprClosure(.., b, _) => { - self.with_context(Closure, |v| v.visit_body(b)); + self.with_context(Closure, |v| v.visit_nested_body(b)); } hir::ExprBreak(label, ref opt_expr) => { if opt_expr.is_some() { diff --git a/src/librustc_passes/rvalues.rs b/src/librustc_passes/rvalues.rs index ddb5af1e80c..e845115cf4f 100644 --- a/src/librustc_passes/rvalues.rs +++ b/src/librustc_passes/rvalues.rs @@ -39,7 +39,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RvalueContext<'a, 'tcx> { fn visit_fn(&mut self, fk: intravisit::FnKind<'tcx>, fd: &'tcx hir::FnDecl, - b: hir::ExprId, + b: hir::BodyId, s: Span, fn_id: ast::NodeId) { // FIXME (@jroesch) change this to be an inference context @@ -50,7 +50,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RvalueContext<'a, 'tcx> { tcx: infcx.tcx, param_env: ¶m_env }; - let body = infcx.tcx.map.expr(b); + let body = infcx.tcx.map.body(b); let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, body); }); diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index 213d85203a7..ba4fc57276b 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -30,7 +30,7 @@ struct CheckCrateVisitor<'a, 'ast: 'a> { // variant definitions with the discriminant expression that applies to // each one. If the variant uses the default values (starting from `0`), // then `None` is stored. - discriminant_map: NodeMap>, + discriminant_map: NodeMap>, detected_recursive_ids: NodeSet, } @@ -108,7 +108,7 @@ struct CheckItemRecursionVisitor<'a, 'b: 'a, 'ast: 'b> { root_span: &'b Span, sess: &'b Session, ast_map: &'b ast_map::Map<'ast>, - discriminant_map: &'a mut NodeMap>, + discriminant_map: &'a mut NodeMap>, idstack: Vec, detected_recursive_ids: &'a mut NodeSet, } @@ -189,7 +189,7 @@ impl<'a, 'b: 'a, 'ast: 'b> CheckItemRecursionVisitor<'a, 'b, 'ast> { variant_stack.push(variant.node.data.id()); // When we find an expression, every variant currently on the stack // is affected by that expression. - if let Some(ref expr) = variant.node.disr_expr { + if let Some(expr) = variant.node.disr_expr { for id in &variant_stack { self.discriminant_map.insert(*id, Some(expr)); } @@ -226,19 +226,15 @@ impl<'a, 'b: 'a, 'ast: 'b> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'b, ' _: &'ast hir::Generics, _: ast::NodeId) { let variant_id = variant.node.data.id(); - let maybe_expr; - if let Some(get_expr) = self.discriminant_map.get(&variant_id) { - // This is necessary because we need to let the `discriminant_map` - // borrow fall out of scope, so that we can reborrow farther down. - maybe_expr = (*get_expr).clone(); - } else { + let maybe_expr = *self.discriminant_map.get(&variant_id).unwrap_or_else(|| { span_bug!(variant.span, "`check_static_recursion` attempted to visit \ variant with unknown discriminant") - } + }); // If `maybe_expr` is `None`, that's because no discriminant is // specified that affects this variant. Thus, no risk of recursion. if let Some(expr) = maybe_expr { + let expr = &self.ast_map.body(expr).value; self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr), expr.span); } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 63bcbfeb23d..865195d3db4 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -576,6 +576,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.span)) .map_or(Def::Err, |d| d.def()); self.record_def(ty.id, PathResolution::new(def)); + } else if let TyKind::Array(ref element, ref length) = ty.node { + self.visit_ty(element); + self.with_constant_rib(|this| { + this.visit_expr(length); + }); + return; } visit::walk_ty(self, ty); } @@ -2733,6 +2739,13 @@ impl<'a> Resolver<'a> { self.visit_ty(ty); } } + + ExprKind::Repeat(ref element, ref count) => { + self.visit_expr(element); + self.with_constant_rib(|this| { + this.visit_expr(count); + }); + } ExprKind::Call(ref callee, ref arguments) => { self.resolve_expr(callee, Some(&expr.node)); for argument in arguments { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a23a2acadb4..3b2520308c7 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1664,8 +1664,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { }; self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0 } - hir::TyArray(ref ty, ref e) => { - if let Ok(length) = eval_length(tcx.global_tcx(), &e, "array length") { + hir::TyArray(ref ty, length) => { + let e = &tcx.map.body(length).value; + if let Ok(length) = eval_length(tcx.global_tcx(), e, "array length") { tcx.mk_array(self.ast_ty_to_ty(rscope, &ty), length) } else { self.tcx().types.err diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 1d81ed7d359..9412c9105c7 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -25,7 +25,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr: &hir::Expr, _capture: hir::CaptureClause, decl: &'gcx hir::FnDecl, - body_id: hir::ExprId, + body_id: hir::BodyId, expected: Expectation<'tcx>) -> Ty<'tcx> { debug!("check_expr_closure(expr={:?},expected={:?})", @@ -39,7 +39,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(ty) => self.deduce_expectations_from_expected_type(ty), None => (None, None), }; - let body = self.tcx.map.expr(body_id); + let body = self.tcx.map.body(body_id); self.check_closure(expr, expected_kind, decl, body, expected_sig) } @@ -47,7 +47,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr: &hir::Expr, opt_kind: Option, decl: &'gcx hir::FnDecl, - body: &'gcx hir::Expr, + body: &'gcx hir::Body, expected_sig: Option>) -> Ty<'tcx> { debug!("check_closure opt_kind={:?} expected_sig={:?}", @@ -73,10 +73,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type); - let fn_sig = self.tcx - .liberate_late_bound_regions(self.tcx.region_maps.call_site_extent(expr.id, body.id), - &fn_ty.sig); - let fn_sig = (**self).normalize_associated_types_in(body.span, body.id, &fn_sig); + let extent = self.tcx.region_maps.call_site_extent(expr.id, body.value.id); + let fn_sig = self.tcx.liberate_late_bound_regions(extent, &fn_ty.sig); + let fn_sig = self.inh.normalize_associated_types_in(body.value.span, + body.value.id, &fn_sig); check_fn(self, hir::Unsafety::Normal, @@ -84,7 +84,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &fn_sig, decl, expr.id, - &body); + body); // Tuple up the arguments and insert the resulting function type into // the `closures` table. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2f39ef0aac6..021aeec47f0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -550,14 +550,25 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { fn visit_ty(&mut self, t: &'tcx hir::Ty) { match t.node { - hir::TyArray(_, ref expr) => { - check_const_with_type(self.ccx, &expr, self.ccx.tcx.types.usize, expr.id); + hir::TyArray(_, length) => { + check_const_with_type(self.ccx, length, self.ccx.tcx.types.usize, length.node_id); } _ => {} } intravisit::walk_ty(self, t); } + + fn visit_expr(&mut self, e: &'tcx hir::Expr) { + match e.node { + hir::ExprRepeat(_, count) => { + check_const_with_type(self.ccx, count, self.ccx.tcx.types.usize, count.node_id); + } + _ => {} + } + + intravisit::walk_expr(self, e); + } } impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { @@ -639,28 +650,28 @@ pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult { fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, decl: &'tcx hir::FnDecl, - body_id: hir::ExprId, + body_id: hir::BodyId, fn_id: ast::NodeId, span: Span) { - let body = ccx.tcx.map.expr(body_id); + let body = ccx.tcx.map.body(body_id); let raw_fty = ccx.tcx.item_type(ccx.tcx.map.local_def_id(fn_id)); let fn_ty = match raw_fty.sty { ty::TyFnDef(.., f) => f, - _ => span_bug!(body.span, "check_bare_fn: function type expected") + _ => span_bug!(body.value.span, "check_bare_fn: function type expected") }; check_abi(ccx, span, fn_ty.abi); ccx.inherited(fn_id).enter(|inh| { // Compute the fty from point of view of inside fn. - let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body_id.node_id()); + let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body_id.node_id); let fn_sig = fn_ty.sig.subst(inh.tcx, &inh.parameter_environment.free_substs); let fn_sig = inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig); let fn_sig = - inh.normalize_associated_types_in(body.span, body_id.node_id(), &fn_sig); + inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig); let fcx = check_fn(&inh, fn_ty.unsafety, fn_id, &fn_sig, decl, fn_id, body); @@ -670,7 +681,7 @@ 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_id); + fcx.regionck_fn(fn_id, decl, body); fcx.resolve_type_vars_in_fn(decl, body, fn_id); }); } @@ -740,21 +751,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> { intravisit::walk_pat(self, p); } - fn visit_block(&mut self, b: &'gcx hir::Block) { - // non-obvious: the `blk` variable maps to region lb, so - // we have to keep this up-to-date. This - // is... unfortunate. It'd be nice to not need this. - intravisit::walk_block(self, b); - } - - // Since an expr occurs as part of the type fixed size arrays we - // need to record the type for that node fn visit_ty(&mut self, t: &'gcx hir::Ty) { match t.node { - hir::TyArray(ref ty, ref count_expr) => { - self.visit_ty(&ty); - self.fcx.check_expr_with_hint(&count_expr, self.fcx.tcx.types.usize); - } hir::TyBareFn(ref function_declaration) => { intravisit::walk_fn_decl_nopat(self, &function_declaration.decl); walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes); @@ -765,7 +763,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> { // Don't descend into the bodies of nested closures fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl, - _: hir::ExprId, _: Span, _: ast::NodeId) { } + _: hir::BodyId, _: Span, _: ast::NodeId) { } } /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function @@ -780,7 +778,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, fn_sig: &ty::FnSig<'tcx>, decl: &'gcx hir::FnDecl, fn_id: ast::NodeId, - body: &'gcx hir::Expr) + body: &'gcx hir::Body) -> FnCtxt<'a, 'gcx, 'tcx> { let mut fn_sig = fn_sig.clone(); @@ -789,7 +787,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, // Create the function context. This is either derived from scratch or, // in the case of function expressions, based on the outer context. - let mut fcx = FnCtxt::new(inherited, None, body.id); + let mut fcx = FnCtxt::new(inherited, None, body.value.id); let ret_ty = fn_sig.output(); *fcx.ps.borrow_mut() = UnsafetyState::function(unsafety, unsafety_id); @@ -822,12 +820,12 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, fcx.write_ty(input.id, arg_ty); } - visit.visit_expr(body); + visit.visit_body(body); } inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig); - fcx.check_expr_coercable_to_type(body, fcx.ret_ty.unwrap()); + fcx.check_expr_coercable_to_type(&body.value, fcx.ret_ty.unwrap()); fcx } @@ -852,8 +850,8 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { let _indenter = indenter(); match it.node { // Consts can play a role in type-checking, so they are included here. - hir::ItemStatic(.., ref e) | - hir::ItemConst(_, ref e) => check_const(ccx, &e, it.id), + hir::ItemStatic(.., e) | + hir::ItemConst(_, e) => check_const(ccx, e, it.id), hir::ItemEnum(ref enum_definition, _) => { check_enum_variants(ccx, it.span, @@ -937,8 +935,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { for impl_item_ref in impl_item_refs { let impl_item = ccx.tcx.map.impl_item(impl_item_ref.id); match impl_item.node { - hir::ImplItemKind::Const(_, ref expr) => { - check_const(ccx, &expr, impl_item.id) + hir::ImplItemKind::Const(_, expr) => { + check_const(ccx, expr, impl_item.id) } hir::ImplItemKind::Method(ref sig, body_id) => { check_bare_fn(ccx, &sig.decl, body_id, impl_item.id, impl_item.span); @@ -953,8 +951,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { for trait_item_ref in trait_item_refs { let trait_item = ccx.tcx.map.trait_item(trait_item_ref.id); match trait_item.node { - hir::TraitItemKind::Const(_, Some(ref expr)) => { - check_const(ccx, &expr, trait_item.id) + hir::TraitItemKind::Const(_, Some(expr)) => { + check_const(ccx, expr, trait_item.id) } hir::TraitItemKind::Method(ref sig, Some(body_id)) => { check_bare_fn(ccx, &sig.decl, body_id, trait_item.id, trait_item.span); @@ -1127,7 +1125,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, compare_impl_method(ccx, &ty_impl_item, impl_item.span, - body_id.node_id(), + body_id.node_id, &ty_trait_item, impl_trait_ref, trait_span, @@ -1137,7 +1135,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, compare_impl_method(ccx, &ty_impl_item, impl_item.span, - body_id.node_id(), + body_id.node_id, &ty_trait_item, impl_trait_ref, trait_span, @@ -1248,37 +1246,38 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, /// Checks a constant with a given type. fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, - expr: &'tcx hir::Expr, + body: hir::BodyId, expected_type: Ty<'tcx>, id: ast::NodeId) { + let body = ccx.tcx.map.body(body); ccx.inherited(id).enter(|inh| { - let fcx = FnCtxt::new(&inh, None, expr.id); - fcx.require_type_is_sized(expected_type, expr.span, traits::ConstSized); + let fcx = FnCtxt::new(&inh, None, body.value.id); + fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized); // Gather locals in statics (because of block expressions). // This is technically unnecessary because locals in static items are forbidden, // but prevents type checking from blowing up before const checking can properly // emit an error. - GatherLocalsVisitor { fcx: &fcx }.visit_expr(expr); + GatherLocalsVisitor { fcx: &fcx }.visit_body(body); - fcx.check_expr_coercable_to_type(expr, expected_type); + fcx.check_expr_coercable_to_type(&body.value, expected_type); fcx.select_all_obligations_and_apply_defaults(); - fcx.closure_analyze(expr); + fcx.closure_analyze(body); fcx.select_obligations_where_possible(); fcx.check_casts(); fcx.select_all_obligations_or_error(); - fcx.regionck_expr(expr); - fcx.resolve_type_vars_in_expr(expr, id); + fcx.regionck_expr(body); + fcx.resolve_type_vars_in_expr(body, id); }); } fn check_const<'a, 'tcx>(ccx: &CrateCtxt<'a,'tcx>, - expr: &'tcx hir::Expr, + body: hir::BodyId, id: ast::NodeId) { let decl_ty = ccx.tcx.item_type(ccx.tcx.map.local_def_id(id)); - check_const_with_type(ccx, expr, decl_ty, id); + check_const_with_type(ccx, body, decl_ty, id); } /// Checks whether a type can be represented in memory. In particular, it @@ -1353,8 +1352,8 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(ccx.tcx); for v in vs { - if let Some(ref e) = v.node.disr_expr { - check_const_with_type(ccx, e, repr_type_ty, e.id); + if let Some(e) = v.node.disr_expr { + check_const_with_type(ccx, e, repr_type_ty, e.node_id); } } @@ -1370,11 +1369,11 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap(); let variant_i = ccx.tcx.map.expect_variant(variant_i_node_id); let i_span = match variant_i.node.disr_expr { - Some(ref expr) => expr.span, + Some(expr) => ccx.tcx.map.span(expr.node_id), None => ccx.tcx.map.span(variant_i_node_id) }; let span = match v.node.disr_expr { - Some(ref expr) => expr.span, + Some(expr) => ccx.tcx.map.span(expr.node_id), None => v.span }; struct_span_err!(ccx.tcx.sess, span, E0081, @@ -1648,12 +1647,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match self.locals.borrow().get(&nid) { Some(&t) => t, None => { - struct_span_err!(self.tcx.sess, span, E0513, - "no type for local variable {}", - self.tcx.map.node_to_string(nid)) - .span_label(span, &"no type for variable") - .emit(); - self.tcx.types.err + span_bug!(span, "no type for local variable {}", + self.tcx.map.node_to_string(nid)); } } } @@ -3826,10 +3821,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref) } hir::ExprCast(ref e, ref t) => { - if let hir::TyArray(_, ref count_expr) = t.node { - self.check_expr_with_hint(&count_expr, tcx.types.usize); - } - // Find the type of `e`. Supply hints based on the type we are casting to, // if appropriate. let t_cast = self.to_ty(t); @@ -3891,9 +3882,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } tcx.mk_array(unified, args.len()) } - hir::ExprRepeat(ref element, ref count_expr) => { - self.check_expr_has_type(&count_expr, tcx.types.usize); - let count = eval_length(self.tcx.global_tcx(), &count_expr, "repeat count") + hir::ExprRepeat(ref element, count) => { + let count_expr = &tcx.map.body(count).value; + let count = eval_length(self.tcx.global_tcx(), count_expr, "repeat count") .unwrap_or(0); let uty = match expected { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index eb08e70d4c3..80b967210f9 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -113,12 +113,13 @@ macro_rules! ignore_err { // PUBLIC ENTRY POINTS impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { - pub fn regionck_expr(&self, e: &'gcx hir::Expr) { - let mut rcx = RegionCtxt::new(self, RepeatingScope(e.id), e.id, Subject(e.id)); + pub fn regionck_expr(&self, body: &'gcx hir::Body) { + let id = body.value.id; + let mut rcx = RegionCtxt::new(self, RepeatingScope(id), id, Subject(id)); if self.err_count_since_creation() == 0 { // regionck assumes typeck succeeded - rcx.visit_expr(e); - rcx.visit_region_obligations(e.id); + rcx.visit_body(body); + rcx.visit_region_obligations(id); } rcx.resolve_regions_and_report_errors(); } @@ -141,14 +142,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn regionck_fn(&self, fn_id: ast::NodeId, decl: &hir::FnDecl, - body_id: hir::ExprId) { + body: &'gcx hir::Body) { debug!("regionck_fn(id={})", fn_id); - let node_id = body_id.node_id(); + let node_id = body.value.id; let mut rcx = RegionCtxt::new(self, RepeatingScope(node_id), node_id, Subject(fn_id)); if self.err_count_since_creation() == 0 { // regionck assumes typeck succeeded - rcx.visit_fn_body(fn_id, decl, body_id, self.tcx.map.span(fn_id)); + rcx.visit_fn_body(fn_id, decl, body, self.tcx.map.span(fn_id)); } rcx.free_region_map.relate_free_regions_from_predicates( @@ -268,14 +269,16 @@ 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_id: hir::ExprId, + body: &'gcx hir::Body, span: Span) { // When we enter a function, we can derive debug!("visit_fn_body(id={})", id); + let body_id = body.id(); + let call_site = self.tcx.region_maps.lookup_code_extent( - region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id() }); + region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id }); let old_call_site_scope = self.set_call_site_scope(Some(call_site)); let fn_sig = { @@ -298,20 +301,19 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let fn_sig_tys: Vec<_> = fn_sig.inputs().iter().cloned().chain(Some(fn_sig.output())).collect(); - 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()), + 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[..]); - let body = self.tcx.map.expr(body_id); - self.visit_expr(body); - self.visit_region_obligations(body_id.node_id()); + self.visit_body(body); + self.visit_region_obligations(body_id.node_id); let call_site_scope = self.call_site_scope.unwrap(); - debug!("visit_fn_body body.id {} call_site_scope: {:?}", - body.id, call_site_scope); + debug!("visit_fn_body body.id {:?} call_site_scope: {:?}", + body.id(), call_site_scope); let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope)); self.type_of_node_must_outlive(infer::CallReturn(span), - body_id.node_id(), + body_id.node_id, call_site_region); self.region_bound_pairs.truncate(old_region_bounds_pairs_len); @@ -478,12 +480,13 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // regions, until regionck, as described in #3238. fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> { - NestedVisitorMap::OnlyBodies(&self.tcx.map) + NestedVisitorMap::None } fn visit_fn(&mut self, _fk: intravisit::FnKind<'gcx>, fd: &'gcx hir::FnDecl, - b: hir::ExprId, span: Span, id: ast::NodeId) { - self.visit_fn_body(id, fd, b, span) + b: hir::BodyId, span: Span, id: ast::NodeId) { + let body = self.tcx.map.body(b); + self.visit_fn_body(id, fd, body, span) } //visit_pat: visit_pat, // (..) see above @@ -826,8 +829,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn check_expr_fn_block(&mut self, expr: &'gcx hir::Expr, - body_id: hir::ExprId) { - let repeating_scope = self.set_repeating_scope(body_id.node_id()); + body_id: hir::BodyId) { + let repeating_scope = self.set_repeating_scope(body_id.node_id); intravisit::walk_expr(self, expr); self.set_repeating_scope(repeating_scope); } diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 63d20416bde..0ad01a0e00d 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -57,12 +57,12 @@ use rustc::util::nodemap::NodeMap; // PUBLIC ENTRY POINTS impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { - pub fn closure_analyze(&self, body: &'gcx hir::Expr) { + pub fn closure_analyze(&self, body: &'gcx hir::Body) { let mut seed = SeedBorrowKind::new(self); - seed.visit_expr(body); + seed.visit_body(body); let mut adjust = AdjustBorrowKind::new(self, seed.temp_closure_kinds); - adjust.visit_expr(body); + adjust.visit_body(body); // it's our job to process these. assert!(self.deferred_call_resolutions.borrow().is_empty()); @@ -79,13 +79,15 @@ struct SeedBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { impl<'a, 'gcx, 'tcx> Visitor<'gcx> for SeedBorrowKind<'a, 'gcx, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> { - NestedVisitorMap::OnlyBodies(&self.fcx.tcx.map) + NestedVisitorMap::None } fn visit_expr(&mut self, expr: &'gcx hir::Expr) { match expr.node { hir::ExprClosure(cc, _, body_id, _) => { - self.check_closure(expr, cc, body_id); + let body = self.fcx.tcx.map.body(body_id); + self.visit_body(body); + self.check_closure(expr, cc); } _ => { } @@ -102,8 +104,7 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> { fn check_closure(&mut self, expr: &hir::Expr, - capture_clause: hir::CaptureClause, - _body_id: hir::ExprId) + capture_clause: hir::CaptureClause) { let closure_def_id = self.fcx.tcx.map.local_def_id(expr.id); if !self.fcx.tables.borrow().closure_kinds.contains_key(&closure_def_id) { @@ -157,15 +158,14 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { id: ast::NodeId, span: Span, decl: &hir::FnDecl, - body_id: hir::ExprId) { + body: &hir::Body) { /*! * Analysis starting point. */ - debug!("analyze_closure(id={:?}, body.id={:?})", id, body_id); + debug!("analyze_closure(id={:?}, body.id={:?})", id, body.id()); { - let body = self.fcx.tcx.map.expr(body_id); let mut euv = euv::ExprUseVisitor::with_options(self, self.fcx, @@ -491,17 +491,20 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> Visitor<'gcx> for AdjustBorrowKind<'a, 'gcx, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> { - NestedVisitorMap::OnlyBodies(&self.fcx.tcx.map) + NestedVisitorMap::None } fn visit_fn(&mut self, fn_kind: intravisit::FnKind<'gcx>, decl: &'gcx hir::FnDecl, - body: hir::ExprId, + body: hir::BodyId, span: Span, id: ast::NodeId) { intravisit::walk_fn(self, fn_kind, decl, body, span, id); + + let body = self.fcx.tcx.map.body(body); + self.visit_body(body); self.analyze_closure(id, span, decl, body); } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index b836bba3dab..4955322963a 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -337,7 +337,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { fn check_item_fn(&mut self, item: &hir::Item, - body_id: hir::ExprId) + body_id: hir::BodyId) { self.for_item(item).with_fcx(|fcx, this| { let free_substs = &fcx.parameter_environment.free_substs; @@ -354,7 +354,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs); let mut implied_bounds = vec![]; - let free_id_outlive = fcx.tcx.region_maps.call_site_extent(item.id, body_id.node_id()); + let free_id_outlive = fcx.tcx.region_maps.call_site_extent(item.id, body_id.node_id); this.check_fn_or_method(fcx, item.span, bare_fn_ty, &predicates, free_id_outlive, &mut implied_bounds); implied_bounds diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 56de75995fd..beed85297fd 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -34,10 +34,10 @@ use rustc::hir::{self, PatKind}; // Entry point functions impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { - pub fn resolve_type_vars_in_expr(&self, e: &'gcx hir::Expr, item_id: ast::NodeId) { + pub fn resolve_type_vars_in_expr(&self, body: &'gcx hir::Body, item_id: ast::NodeId) { assert_eq!(self.writeback_errors.get(), false); let mut wbcx = WritebackCx::new(self); - wbcx.visit_expr(e); + wbcx.visit_body(body); wbcx.visit_upvar_borrow_map(); wbcx.visit_closures(); wbcx.visit_liberated_fn_sigs(); @@ -48,11 +48,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn resolve_type_vars_in_fn(&self, decl: &'gcx hir::FnDecl, - body: &'gcx hir::Expr, + body: &'gcx hir::Body, item_id: ast::NodeId) { assert_eq!(self.writeback_errors.get(), false); let mut wbcx = WritebackCx::new(self); - wbcx.visit_expr(body); + wbcx.visit_body(body); for arg in &decl.inputs { wbcx.visit_node_id(ResolvingPattern(arg.pat.span), arg.id); wbcx.visit_pat(&arg.pat); @@ -188,7 +188,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> { - NestedVisitorMap::OnlyBodies(&self.fcx.tcx.map) + NestedVisitorMap::None } fn visit_stmt(&mut self, s: &'gcx hir::Stmt) { @@ -211,10 +211,13 @@ 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, ..) = e.node { + if let hir::ExprClosure(_, ref decl, body, _) = e.node { for input in &decl.inputs { self.visit_node_id(ResolvingExpr(e.span), input.id); } + + let body = self.fcx.tcx.map.body(body); + self.visit_body(body); } intravisit::walk_expr(self, e); @@ -257,10 +260,6 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { fn visit_ty(&mut self, t: &'gcx hir::Ty) { match t.node { - hir::TyArray(ref ty, ref count_expr) => { - self.visit_ty(&ty); - self.write_ty_to_tcx(count_expr.id, self.tcx().types.usize); - } hir::TyBareFn(ref function_declaration) => { intravisit::walk_fn_decl_nopat(self, &function_declaration.decl); walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 5e41ee70dd2..cb9e1c989e3 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1095,7 +1095,8 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let mut prev_disr = None::; let variants = def.variants.iter().map(|v| { let wrapped_disr = prev_disr.map_or(initial, |d| d.wrap_incr()); - let disr = if let Some(ref e) = v.node.disr_expr { + let disr = if let Some(e) = v.node.disr_expr { + let e = &tcx.map.body(e).value; evaluate_disr_expr(ccx, repr_type, e) } else if let Some(disr) = repr_type.disr_incr(tcx, prev_disr) { Some(disr) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index cea3ad43a95..d3b671f2a4d 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3866,45 +3866,6 @@ extern "platform-intrinsic" { ``` "##, -E0513: r##" -The type of the variable couldn't be found out. - -Erroneous code example: - -```compile_fail,E0513 -use std::mem; - -unsafe { - let size = mem::size_of::(); - mem::transmute_copy::(&8_8); - // error: no type for local variable -} -``` - -To fix this error, please use a constant size instead of `size`. To make -this error more obvious, you could run: - -```compile_fail,E0080 -use std::mem; - -unsafe { - mem::transmute_copy::()]>(&8_8); - // error: constant evaluation error -} -``` - -So now, you can fix your code by setting the size directly: - -``` -use std::mem; - -unsafe { - mem::transmute_copy::(&8_8); - // `u32` is 4 bytes so we replace the `mem::size_of` call with its size -} -``` -"##, - E0516: r##" The `typeof` keyword is currently reserved but unimplemented. Erroneous code example: diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 34e6aa5528b..40f005fecbd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1270,9 +1270,9 @@ impl Clean for hir::PolyTraitRef { impl Clean for hir::TraitItem { fn clean(&self, cx: &DocContext) -> Item { let inner = match self.node { - hir::TraitItemKind::Const(ref ty, ref default) => { + hir::TraitItemKind::Const(ref ty, default) => { AssociatedConstItem(ty.clean(cx), - default.as_ref().map(|e| pprust::expr_to_string(&e))) + default.map(|e| print_const_expr(cx, e))) } hir::TraitItemKind::Method(ref sig, Some(_)) => { MethodItem(sig.clean(cx)) @@ -1300,9 +1300,9 @@ impl Clean for hir::TraitItem { impl Clean for hir::ImplItem { fn clean(&self, cx: &DocContext) -> Item { let inner = match self.node { - hir::ImplItemKind::Const(ref ty, ref expr) => { + hir::ImplItemKind::Const(ref ty, expr) => { AssociatedConstItem(ty.clean(cx), - Some(pprust::expr_to_string(expr))) + Some(print_const_expr(cx, expr))) } hir::ImplItemKind::Method(ref sig, _) => { MethodItem(sig.clean(cx)) @@ -1687,11 +1687,12 @@ impl Clean for hir::Ty { BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx), type_: box m.ty.clean(cx)}, TySlice(ref ty) => Vector(box ty.clean(cx)), - TyArray(ref ty, ref e) => { + TyArray(ref ty, e) => { use rustc_const_math::{ConstInt, ConstUsize}; use rustc_const_eval::eval_const_expr; use rustc::middle::const_val::ConstVal; + let e = &cx.tcx.map.body(e).value; let n = match eval_const_expr(cx.tcx, e) { ConstVal::Integral(ConstInt::Usize(u)) => match u { ConstUsize::Us16(u) => u.to_string(), @@ -2372,7 +2373,7 @@ impl Clean for doctree::Static { inner: StaticItem(Static { type_: self.type_.clean(cx), mutability: self.mutability.clean(cx), - expr: pprust::expr_to_string(&self.expr), + expr: print_const_expr(cx, self.expr), }), } } @@ -2396,7 +2397,7 @@ impl Clean for doctree::Constant { deprecation: self.depr.clean(cx), inner: ConstantItem(Constant { type_: self.type_.clean(cx), - expr: pprust::expr_to_string(&self.expr), + expr: print_const_expr(cx, self.expr), }), } } @@ -2724,6 +2725,10 @@ fn name_from_pat(p: &hir::Pat) -> String { } } +fn print_const_expr(cx: &DocContext, body: hir::BodyId) -> String { + pprust::expr_to_string(&cx.tcx.map.body(body).value) +} + /// Given a type Path, resolve it to a Type using the TyCtxt fn resolve_type(cx: &DocContext, path: Path, diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 31e10fbd3b7..46b1ed2aa24 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -174,7 +174,7 @@ pub struct Typedef { pub struct Static { pub type_: P, pub mutability: hir::Mutability, - pub expr: P, + pub expr: hir::BodyId, pub name: Name, pub attrs: hir::HirVec, pub vis: hir::Visibility, @@ -186,7 +186,7 @@ pub struct Static { pub struct Constant { pub type_: P, - pub expr: P, + pub expr: hir::BodyId, pub name: Name, pub attrs: hir::HirVec, pub vis: hir::Visibility, diff --git a/src/test/compile-fail/E0513.rs b/src/test/compile-fail/E0513.rs deleted file mode 100644 index 726e2326524..00000000000 --- a/src/test/compile-fail/E0513.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; - -fn main() { - unsafe { - let size = mem::size_of::(); - mem::transmute_copy::(&8_8); //~ ERROR E0513 - //~| NOTE no type for variable - } -} diff --git a/src/test/compile-fail/associated-const-type-parameter-arrays-2.rs b/src/test/compile-fail/associated-const-type-parameter-arrays-2.rs index c3fa39659b9..7c3f7a1d574 100644 --- a/src/test/compile-fail/associated-const-type-parameter-arrays-2.rs +++ b/src/test/compile-fail/associated-const-type-parameter-arrays-2.rs @@ -25,8 +25,10 @@ impl Foo for Def { } pub fn test() { - let _array = [4; ::Y]; //~ ERROR E0080 - //~| non-constant path in constant + let _array = [4; ::Y]; + //~^ ERROR cannot use an outer type parameter in this context [E0402] + //~| ERROR constant evaluation error [E0080] + //~| non-constant path in constant } fn main() { diff --git a/src/test/compile-fail/associated-const-type-parameter-arrays.rs b/src/test/compile-fail/associated-const-type-parameter-arrays.rs index ddf16a2278e..dcf87d5f0fc 100644 --- a/src/test/compile-fail/associated-const-type-parameter-arrays.rs +++ b/src/test/compile-fail/associated-const-type-parameter-arrays.rs @@ -26,7 +26,9 @@ impl Foo for Def { pub fn test() { let _array: [u32; ::Y]; - //~^ ERROR the trait bound `A: Foo` is not satisfied + //~^ ERROR cannot use an outer type parameter in this context [E0402] + //~| ERROR constant evaluation error [E0080] + //~| non-constant path in constant } fn main() { diff --git a/src/test/compile-fail/issue-27008.rs b/src/test/compile-fail/issue-27008.rs index e89bff025e0..f80135848e0 100644 --- a/src/test/compile-fail/issue-27008.rs +++ b/src/test/compile-fail/issue-27008.rs @@ -16,6 +16,4 @@ fn main() { //~| expected type `usize` //~| found type `S` //~| expected usize, found struct `S` - //~| ERROR expected `usize` for repeat count, found struct [E0306] - //~| expected `usize` } diff --git a/src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs b/src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs index b5401f7d124..691d8d31b41 100644 --- a/src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs +++ b/src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs @@ -12,8 +12,8 @@ fn main() { fn bar(n: isize) { - // FIXME (#24414): This error message needs improvement. let _x: [isize; n]; - //~^ ERROR no type for local variable + //~^ ERROR attempt to use a non-constant value in a constant [E0435] + //~| ERROR constant evaluation error [E0080] } } diff --git a/src/test/compile-fail/non-constant-expr-for-vec-repeat.rs b/src/test/compile-fail/non-constant-expr-for-vec-repeat.rs index a6f88a57b91..f4769a78587 100644 --- a/src/test/compile-fail/non-constant-expr-for-vec-repeat.rs +++ b/src/test/compile-fail/non-constant-expr-for-vec-repeat.rs @@ -13,8 +13,9 @@ fn main() { fn bar(n: usize) { let _x = [0; n]; - //~^ ERROR constant evaluation error - //~| non-constant path in constant expression - //~| NOTE `n` is a variable + //~^ ERROR attempt to use a non-constant value in a constant [E0435] + //~| NOTE non-constant used with constant + //~| NOTE unresolved path in constant expression + //~| ERROR constant evaluation error [E0080] } } diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index 5d5113ce07c..a716f3e29d4 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -13,43 +13,30 @@ fn main() { let n = 1; let a = [0; n]; - //~^ ERROR constant evaluation error - //~| non-constant path in constant expression + //~^ ERROR attempt to use a non-constant value in a constant [E0435] let b = [0; ()]; //~^ ERROR mismatched types //~| expected type `usize` //~| found type `()` //~| expected usize, found () - //~| ERROR expected `usize` for repeat count, found tuple [E0306] - //~| expected `usize` let c = [0; true]; //~^ ERROR mismatched types //~| expected usize, found bool - //~| ERROR expected `usize` for repeat count, found boolean [E0306] - //~| expected `usize` let d = [0; 0.5]; //~^ ERROR mismatched types //~| expected type `usize` //~| found type `{float}` //~| expected usize, found floating-point variable - //~| ERROR expected `usize` for repeat count, found float [E0306] - //~| expected `usize` let e = [0; "foo"]; //~^ ERROR mismatched types //~| expected type `usize` //~| found type `&'static str` //~| expected usize, found reference - //~| ERROR expected `usize` for repeat count, found string literal [E0306] - //~| expected `usize` let f = [0; -4_isize]; - //~^ ERROR constant evaluation error - //~| expected usize, found isize - //~| ERROR mismatched types + //~^ ERROR mismatched types //~| expected usize, found isize let f = [0_usize; -1_isize]; - //~^ ERROR constant evaluation error - //~| expected usize, found isize - //~| ERROR mismatched types + //~^ ERROR mismatched types //~| expected usize, found isize struct G { g: (), @@ -59,6 +46,4 @@ fn main() { //~| expected type `usize` //~| found type `main::G` //~| expected usize, found struct `main::G` - //~| ERROR expected `usize` for repeat count, found struct [E0306] - //~| expected `usize` } diff --git a/src/test/incremental/hashes/consts.rs b/src/test/incremental/hashes/consts.rs index 10c02d84b38..28e85c94b66 100644 --- a/src/test/incremental/hashes/consts.rs +++ b/src/test/incremental/hashes/consts.rs @@ -66,8 +66,10 @@ const CONST_CHANGE_TYPE_2: Option = None; const CONST_CHANGE_VALUE_1: i16 = 1; #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfail2")] +#[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")] const CONST_CHANGE_VALUE_1: i16 = 2; @@ -78,8 +80,10 @@ const CONST_CHANGE_VALUE_1: i16 = 2; const CONST_CHANGE_VALUE_2: i16 = 1 + 1; #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfail2")] +#[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")] const CONST_CHANGE_VALUE_2: i16 = 1 + 2; @@ -89,8 +93,10 @@ const CONST_CHANGE_VALUE_2: i16 = 1 + 2; const CONST_CHANGE_VALUE_3: i16 = 2 + 3; #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfail2")] +#[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")] const CONST_CHANGE_VALUE_3: i16 = 2 * 3; @@ -100,8 +106,10 @@ const CONST_CHANGE_VALUE_3: i16 = 2 * 3; const CONST_CHANGE_VALUE_4: i16 = 1 + 2 * 3; #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfail2")] +#[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")] const CONST_CHANGE_VALUE_4: i16 = 1 + 2 * 4; diff --git a/src/test/incremental/hashes/enum_defs.rs b/src/test/incremental/hashes/enum_defs.rs index aa17a24be23..da3a953d11e 100644 --- a/src/test/incremental/hashes/enum_defs.rs +++ b/src/test/incremental/hashes/enum_defs.rs @@ -108,8 +108,10 @@ enum EnumChangeValueCStyleVariant0 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfail2")] +#[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")] enum EnumChangeValueCStyleVariant0 { @@ -126,6 +128,8 @@ enum EnumChangeValueCStyleVariant1 { #[cfg(not(cfail1))] #[rustc_dirty(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_clean(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] #[rustc_metadata_dirty(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] enum EnumChangeValueCStyleVariant1 { diff --git a/src/test/incremental/hashes/statics.rs b/src/test/incremental/hashes/statics.rs index ac67e434901..7c6da3ba9fe 100644 --- a/src/test/incremental/hashes/statics.rs +++ b/src/test/incremental/hashes/statics.rs @@ -119,9 +119,11 @@ static STATIC_CHANGE_TYPE_2: Option = None; static STATIC_CHANGE_VALUE_1: i16 = 1; #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_dirty(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] static STATIC_CHANGE_VALUE_1: i16 = 2; @@ -131,9 +133,11 @@ static STATIC_CHANGE_VALUE_1: i16 = 2; static STATIC_CHANGE_VALUE_2: i16 = 1 + 1; #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_dirty(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] static STATIC_CHANGE_VALUE_2: i16 = 1 + 2; @@ -142,9 +146,11 @@ static STATIC_CHANGE_VALUE_2: i16 = 1 + 2; static STATIC_CHANGE_VALUE_3: i16 = 2 + 3; #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_dirty(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] static STATIC_CHANGE_VALUE_3: i16 = 2 * 3; @@ -153,9 +159,11 @@ static STATIC_CHANGE_VALUE_3: i16 = 2 * 3; static STATIC_CHANGE_VALUE_4: i16 = 1 + 2 * 3; #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfail2")] +#[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] -#[rustc_metadata_dirty(cfg="cfail2")] +#[rustc_dirty(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] +#[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] static STATIC_CHANGE_VALUE_4: i16 = 1 + 2 * 4; diff --git a/src/test/incremental/string_constant.rs b/src/test/incremental/string_constant.rs index ba8d3cc934b..8651a67bae2 100644 --- a/src/test/incremental/string_constant.rs +++ b/src/test/incremental/string_constant.rs @@ -23,14 +23,14 @@ fn main() { } mod x { #[cfg(rpass1)] pub fn x() { - println!("1"); + println!("{}", "1"); } #[cfg(rpass2)] #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] #[rustc_dirty(label="TransCrateItem", cfg="rpass2")] pub fn x() { - println!("2"); + println!("{}", "2"); } } diff --git a/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs b/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs index c6892757c68..e1b1b441894 100644 --- a/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs +++ b/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs @@ -41,12 +41,12 @@ impl LintPass for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_fn(&mut self, cx: &LateContext, - fk: FnKind, _: &hir::FnDecl, expr: &hir::Expr, + fk: FnKind, _: &hir::FnDecl, body: &hir::Body, span: Span, node: ast::NodeId) { if let FnKind::Closure(..) = fk { return } - let mut extent = cx.tcx.region_maps.node_extent(expr.id); + let mut extent = cx.tcx.region_maps.node_extent(body.value.id); while let Some(parent) = cx.tcx.region_maps.opt_encl_scope(extent) { extent = parent; }