diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 397d61d5372e0..0c941a4a2301f 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -42,6 +42,10 @@ pub enum DepNode { // Represents the HIR node with the given node-id Hir(D), + // Represents the body of a function or method. The def-id is that of the + // function/method. + HirBody(D), + // Represents the metadata for a given HIR node, typically found // in an extern crate. MetaData(D), @@ -59,6 +63,7 @@ pub enum DepNode { PluginRegistrar, StabilityIndex, CollectItem(D), + CollectItemSig(D), Coherence, EffectCheck, Liveness, @@ -150,6 +155,7 @@ impl DepNode { CollectItem, BorrowCheck, Hir, + HirBody, TransCrateItem, TypeckItemType, TypeckItemBody, @@ -199,8 +205,10 @@ impl DepNode { WorkProduct(ref id) => Some(WorkProduct(id.clone())), Hir(ref d) => op(d).map(Hir), + HirBody(ref d) => op(d).map(HirBody), MetaData(ref d) => op(d).map(MetaData), CollectItem(ref d) => op(d).map(CollectItem), + CollectItemSig(ref d) => op(d).map(CollectItemSig), CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl), CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck), CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial), diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 94da10d33f818..625bde2ca8b67 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -67,6 +67,62 @@ impl<'a> FnKind<'a> { } } +/// Specifies what nested things a visitor wants to visit. The most +/// common choice is `OnlyBodies`, which will cause the visitor to +/// visit fn bodies for fns that it encounters, but skip over nested +/// item-like things. +/// +/// See the comments on `ItemLikeVisitor` for more details on the overall +/// visit strategy. +pub enum NestedVisitorMap<'this, 'tcx: 'this> { + /// Do not visit any nested things. When you add a new + /// "non-nested" thing, you will want to audit such uses to see if + /// they remain valid. + /// + /// Use this if you are only walking some particular kind of tree + /// (i.e., a type, or fn signature) and you don't want to thread a + /// HIR map around. + None, + + /// Do not visit nested item-like things, but visit nested things + /// that are inside of an item-like. + /// + /// **This is the most common choice.** A very commmon pattern is + /// to use `tcx.visit_all_item_likes_in_krate()` as an outer loop, + /// and to have the visitor that visits the contents of each item + /// using this setting. + OnlyBodies(&'this Map<'tcx>), + + /// Visit all nested things, including item-likes. + /// + /// **This is an unusual choice.** It is used when you want to + /// process everything within their lexical context. Typically you + /// kick off the visit by doing `walk_krate()`. + All(&'this Map<'tcx>), +} + +impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> { + /// Returns the map to use for an "intra item-like" thing (if any). + /// e.g., function body. + pub fn intra(self) -> Option<&'this Map<'tcx>> { + match self { + NestedVisitorMap::None => None, + NestedVisitorMap::OnlyBodies(map) => Some(map), + NestedVisitorMap::All(map) => Some(map), + } + } + + /// Returns the map to use for an "item-like" thing (if any). + /// e.g., item, impl-item. + pub fn inter(self) -> Option<&'this Map<'tcx>> { + match self { + NestedVisitorMap::None => None, + NestedVisitorMap::OnlyBodies(_) => None, + NestedVisitorMap::All(map) => Some(map), + } + } +} + /// Each method of the Visitor trait is a hook to be potentially /// overridden. Each method's default implementation recursively visits /// the substructure of the input via the corresponding `walk` method; @@ -88,13 +144,14 @@ pub trait Visitor<'v> : Sized { // Nested items. /// The default versions of the `visit_nested_XXX` routines invoke - /// this method to get a map to use; if they get back `None`, they - /// just skip nested things. Otherwise, they will lookup the - /// nested item-like things in the map and visit it. So the best - /// way to implement a nested visitor is to override this method - /// to return a `Map`; one advantage of this is that if we add - /// more types of nested things in the future, they will - /// automatically work. + /// this method to get a map to use. By selecting an enum variant, + /// you control which kinds of nested HIR are visited; see + /// `NestedVisitorMap` for details. By "nested HIR", we are + /// referring to bits of HIR that are not directly embedded within + /// one another but rather indirectly, through a table in the + /// crate. This is done to control dependencies during incremental + /// compilation: the non-inline bits of HIR can be tracked and + /// hashed separately. /// /// **If for some reason you want the nested behavior, but don't /// have a `Map` are your disposal:** then you should override the @@ -102,9 +159,7 @@ pub trait Visitor<'v> : Sized { /// `panic!()`. This way, if a new `visit_nested_XXX` variant is /// added in the future, we will see the panic in your code and /// fix it appropriately. - fn nested_visit_map(&mut self) -> Option<&Map<'v>> { - None - } + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v>; /// Invoked when a nested item is encountered. By default does /// nothing unless you override `nested_visit_map` to return @@ -116,8 +171,7 @@ pub trait Visitor<'v> : Sized { /// but cannot supply a `Map`; see `nested_visit_map` for advice. #[allow(unused_variables)] fn visit_nested_item(&mut self, id: ItemId) { - let opt_item = self.nested_visit_map() - .map(|map| map.expect_item(id.id)); + let opt_item = self.nested_visit_map().inter().map(|map| map.expect_item(id.id)); if let Some(item) = opt_item { self.visit_item(item); } @@ -128,13 +182,23 @@ pub trait Visitor<'v> : Sized { /// method. #[allow(unused_variables)] fn visit_nested_impl_item(&mut self, id: ImplItemId) { - let opt_item = self.nested_visit_map() - .map(|map| map.impl_item(id)); + let opt_item = self.nested_visit_map().inter().map(|map| map.impl_item(id)); if let Some(item) = opt_item { self.visit_impl_item(item); } } + /// Invoked to visit the body of a function, method or closure. Like + /// 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); + } + } + /// Visit the top-level item and (optionally) nested items / impl items. See /// `visit_nested_item` for details. fn visit_item(&mut self, i: &'v Item) { @@ -200,7 +264,7 @@ pub trait Visitor<'v> : Sized { fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) { walk_where_predicate(self, predicate) } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Expr, s: Span, id: NodeId) { + fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: ExprId, s: Span, id: NodeId) { walk_fn(self, fk, fd, b, s, id) } fn visit_trait_item(&mut self, ti: &'v TraitItem) { @@ -363,7 +427,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_ty(typ); visitor.visit_expr(expr); } - ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => { + ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => { visitor.visit_fn(FnKind::ItemFn(item.name, generics, unsafety, @@ -372,7 +436,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { &item.vis, &item.attrs), declaration, - body, + body_id, item.span, item.id) } @@ -697,13 +761,25 @@ 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, - function_body: &'v Expr, + body_id: ExprId, _span: Span, id: NodeId) { visitor.visit_id(id); walk_fn_decl(visitor, function_declaration); walk_fn_kind(visitor, function_kind); - visitor.visit_expr(function_body) + 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); + walk_fn_decl(visitor, function_declaration); + walk_fn_kind(visitor, function_kind); + visitor.visit_expr(body) } pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) { @@ -720,13 +796,13 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai visitor.visit_generics(&sig.generics); walk_fn_decl(visitor, &sig.decl); } - MethodTraitItem(ref sig, Some(ref body)) => { + MethodTraitItem(ref sig, Some(body_id)) => { visitor.visit_fn(FnKind::Method(trait_item.name, sig, None, &trait_item.attrs), &sig.decl, - body, + body_id, trait_item.span, trait_item.id); } @@ -752,13 +828,13 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt visitor.visit_ty(ty); visitor.visit_expr(expr); } - ImplItemKind::Method(ref sig, ref body) => { + ImplItemKind::Method(ref sig, body_id) => { visitor.visit_fn(FnKind::Method(impl_item.name, sig, Some(&impl_item.vis), &impl_item.attrs), &sig.decl, - body, + body_id, impl_item.span, impl_item.id); } @@ -883,7 +959,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(subexpression); walk_list!(visitor, visit_arm, arms); } - ExprClosure(_, ref function_declaration, ref body, _fn_decl_span) => { + ExprClosure(_, ref function_declaration, body, _fn_decl_span) => { visitor.visit_fn(FnKind::Closure(&expression.attrs), function_declaration, body, @@ -998,13 +1074,14 @@ impl IdRange { } -pub struct IdRangeComputingVisitor { - pub result: IdRange, +pub struct IdRangeComputingVisitor<'a, 'ast: 'a> { + result: IdRange, + map: &'a map::Map<'ast>, } -impl IdRangeComputingVisitor { - pub fn new() -> IdRangeComputingVisitor { - IdRangeComputingVisitor { result: IdRange::max() } +impl<'a, 'ast> IdRangeComputingVisitor<'a, 'ast> { + pub fn new(map: &'a map::Map<'ast>) -> IdRangeComputingVisitor<'a, 'ast> { + IdRangeComputingVisitor { result: IdRange::max(), map: map } } pub fn result(&self) -> IdRange { @@ -1012,20 +1089,25 @@ impl IdRangeComputingVisitor { } } -impl<'v> Visitor<'v> for IdRangeComputingVisitor { +impl<'a, 'ast> Visitor<'ast> for IdRangeComputingVisitor<'a, 'ast> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { + NestedVisitorMap::OnlyBodies(&self.map) + } + fn visit_id(&mut self, id: NodeId) { self.result.add(id); } } /// Computes the id range for a single fn body, ignoring nested items. -pub fn compute_id_range_for_fn_body(fk: FnKind, - decl: &FnDecl, - body: &Expr, - sp: Span, - id: NodeId) - -> IdRange { - let mut visitor = IdRangeComputingVisitor::new(); - visitor.visit_fn(fk, decl, body, sp, id); +pub fn compute_id_range_for_fn_body<'v>(fk: FnKind<'v>, + decl: &'v FnDecl, + body: &'v Expr, + 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.result() } diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs index 1e373441e9e85..71ef7131440b8 100644 --- a/src/librustc/hir/itemlikevisit.rs +++ b/src/librustc/hir/itemlikevisit.rs @@ -41,8 +41,10 @@ use super::intravisit::Visitor; /// item-like things. /// - Example: Lifetime resolution, which wants to bring lifetimes declared on the /// impl into scope while visiting the impl-items, and then back out again. -/// - How: Implement `intravisit::Visitor` and override the `visit_nested_foo()` foo methods -/// as needed. Walk your crate with `intravisit::walk_crate()` invoked on `tcx.map.krate()`. +/// - How: Implement `intravisit::Visitor` and override the +/// `visit_nested_map()` methods to return +/// `NestedVisitorMap::All`. Walk your crate with +/// `intravisit::walk_crate()` invoked on `tcx.map.krate()`. /// - Pro: Visitor methods for any kind of HIR node, not just item-like things. /// - Pro: Preserves nesting information /// - Con: Does not integrate well into dependency tracking. diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f9f46558dece3..ccf94e0b803db 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -47,9 +47,12 @@ 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 std::collections::BTreeMap; use std::iter; +use std::mem; + use syntax::ast::*; use syntax::errors; use syntax::ptr::P; @@ -68,6 +71,7 @@ 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. @@ -104,6 +108,7 @@ 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(), impl_items: BTreeMap::new(), @@ -120,6 +125,23 @@ enum ParamMode { impl<'a> LoweringContext<'a> { fn lower_crate(mut self, c: &Crate) -> hir::Crate { + self.lower_items(c); + let module = self.lower_mod(&c.module); + let attrs = self.lower_attrs(&c.attrs); + let exported_macros = c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(); + + hir::Crate { + module: module, + attrs: attrs, + span: c.span, + exported_macros: exported_macros, + items: self.items, + impl_items: self.impl_items, + exprs: mem::replace(&mut self.exprs, FnvHashMap()), + } + } + + fn lower_items(&mut self, c: &Crate) { struct ItemLowerer<'lcx, 'interner: 'lcx> { lctx: &'lcx mut LoweringContext<'interner>, } @@ -139,16 +161,14 @@ impl<'a> LoweringContext<'a> { } } - visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c); + let mut item_lowerer = ItemLowerer { lctx: self }; + visit::walk_crate(&mut item_lowerer, c); + } - hir::Crate { - module: self.lower_mod(&c.module), - attrs: self.lower_attrs(&c.attrs), - span: c.span, - exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(), - items: self.items, - impl_items: self.impl_items, - } + fn record_expr(&mut self, expr: hir::Expr) -> hir::ExprId { + let id = hir::ExprId(expr.id); + self.exprs.insert(id, expr); + id } fn next_id(&self) -> NodeId { @@ -825,12 +845,14 @@ impl<'a> LoweringContext<'a> { } 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); hir::ItemFn(self.lower_fn_decl(decl), self.lower_unsafety(unsafety), self.lower_constness(constness), abi, self.lower_generics(generics), - P(self.expr_block(body, ThinVec::new()))) + body_id) } ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)), ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)), @@ -897,7 +919,8 @@ impl<'a> LoweringContext<'a> { hir::MethodTraitItem(this.lower_method_sig(sig), body.as_ref().map(|x| { let body = this.lower_block(x); - P(this.expr_block(body, ThinVec::new())) + let expr = this.expr_block(body, ThinVec::new()); + this.record_expr(expr) })) } TraitItemKind::Type(ref bounds, ref default) => { @@ -925,8 +948,9 @@ impl<'a> LoweringContext<'a> { } ImplItemKind::Method(ref sig, ref body) => { let body = this.lower_block(body); - hir::ImplItemKind::Method(this.lower_method_sig(sig), - P(this.expr_block(body, ThinVec::new()))) + 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) } ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)), ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), @@ -1375,9 +1399,10 @@ impl<'a> LoweringContext<'a> { } ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => { self.with_parent_def(e.id, |this| { + let expr = this.lower_expr(body); hir::ExprClosure(this.lower_capture_clause(capture_clause), this.lower_fn_decl(decl), - P(this.lower_expr(body)), + this.record_expr(expr), fn_decl_span) }) } diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index 325a90ea91e0e..068e7ed8624ed 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: &'a Expr, + pub body: ast::ExprId, 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: &'a Expr, + body: ast::ExprId, 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: &'a Expr, + body: ast::ExprId, id: NodeId, span: Span, attrs: &'a [Attribute], } impl<'a> ClosureParts<'a> { - fn new(d: &'a FnDecl, b: &'a Expr, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self { + fn new(d: &'a FnDecl, b: ast::ExprId, 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) -> &'a Expr { - self.handle(|i: ItemFnParts<'a>| &*i.body, - |_, _, _: &'a ast::MethodSig, _, body: &'a ast::Expr, _, _| body, + pub fn body(self) -> ast::ExprId { + self.handle(|i: ItemFnParts<'a>| i.body, + |_, _, _: &'a ast::MethodSig, _, body: ast::ExprId, _, _| body, |c: ClosureParts<'a>| c.body) } @@ -196,6 +196,18 @@ impl<'a> FnLikeNode<'a> { |c: ClosureParts| c.id) } + pub fn constness(self) -> ast::Constness { + match self.kind() { + FnKind::ItemFn(_, _, _, constness, ..) => { + constness + } + FnKind::Method(_, m, ..) => { + m.constness + } + _ => ast::Constness::NotConst + } + } + pub fn kind(self) -> FnKind<'a> { let item = |p: ItemFnParts<'a>| -> FnKind<'a> { FnKind::ItemFn(p.name, p.generics, p.unsafety, p.constness, p.abi, p.vis, p.attrs) @@ -215,7 +227,7 @@ impl<'a> FnLikeNode<'a> { Name, &'a ast::MethodSig, Option<&'a ast::Visibility>, - &'a ast::Expr, + ast::ExprId, Span, &'a [Attribute]) -> A, @@ -223,13 +235,13 @@ impl<'a> FnLikeNode<'a> { { match self.node { map::NodeItem(i) => match i.node { - ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, ref block) => + ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, block) => item_fn(ItemFnParts { id: i.id, name: i.name, decl: &decl, unsafety: unsafety, - body: &block, + body: block, generics: generics, abi: abi, vis: &i.vis, @@ -240,24 +252,24 @@ impl<'a> FnLikeNode<'a> { _ => bug!("item FnLikeNode that is not fn-like"), }, map::NodeTraitItem(ti) => match ti.node { - ast::MethodTraitItem(ref sig, Some(ref body)) => { + ast::MethodTraitItem(ref sig, Some(body)) => { method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs) } _ => bug!("trait method FnLikeNode that is not fn-like"), }, map::NodeImplItem(ii) => { match ii.node { - ast::ImplItemKind::Method(ref sig, ref body) => { + ast::ImplItemKind::Method(ref sig, body) => { method(ii.id, ii.name, sig, Some(&ii.vis), body, ii.span, &ii.attrs) } _ => { bug!("impl method FnLikeNode that is not fn-like") } } - } + }, map::NodeExpr(e) => match e.node { - ast::ExprClosure(_, ref decl, ref block, _fn_decl_span) => - closure(ClosureParts::new(&decl, &block, e.id, e.span, &e.attrs)), + ast::ExprClosure(_, ref decl, block, _fn_decl_span) => + closure(ClosureParts::new(&decl, block, e.id, e.span, &e.attrs)), _ => bug!("expr FnLikeNode that is not fn-like"), }, _ => bug!("other FnLikeNode that is not fn-like"), diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 26fd2b736a42c..c46c8f044e0ff 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -10,7 +10,7 @@ use super::*; -use hir::intravisit::Visitor; +use hir::intravisit::{Visitor, NestedVisitorMap}; use hir::def_id::DefId; use middle::cstore::InlinedItem; use std::iter::repeat; @@ -91,7 +91,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { /// deep walking so that we walk nested items in the context of /// their outer items. - fn nested_visit_map(&mut self) -> Option<&map::Map<'ast>> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { panic!("visit_nested_xxx must be manually implemented in this visitor") } @@ -106,6 +106,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { 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_item(&mut self, i: &'ast Item) { debug!("visit_item: {:?}", i); @@ -209,7 +213,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, - b: &'ast Expr, s: Span, id: NodeId) { + b: ExprId, s: Span, id: NodeId) { assert_eq!(self.parent_node, id); intravisit::walk_fn(self, fk, fd, b, s, id); } diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index a08060e792778..273094b735c3a 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -11,7 +11,7 @@ use hir::map::definitions::*; use hir; -use hir::intravisit; +use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; use middle::cstore::InlinedItem; @@ -326,7 +326,18 @@ impl<'a> visit::Visitor for DefCollector<'a> { } // We walk the HIR rather than the AST when reading items from metadata. -impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> { +impl<'ast> Visitor<'ast> for DefCollector<'ast> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { + // note however that we override `visit_body` below + NestedVisitorMap::None + } + + fn visit_body(&mut self, id: hir::ExprId) { + if let Some(krate) = self.hir_crate { + self.visit_expr(krate.expr(id)); + } + } + fn visit_item(&mut self, i: &'ast hir::Item) { debug!("visit_item: {:?}", i); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b9763e6ea0dcb..434e34e7003df 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -18,7 +18,6 @@ pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, use dep_graph::{DepGraph, DepNode}; use middle::cstore::InlinedItem; -use middle::cstore::InlinedItem as II; use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; use syntax::abi::Abi; @@ -61,6 +60,8 @@ pub enum Node<'ast> { NodeLifetime(&'ast Lifetime), NodeTyParam(&'ast TyParam), NodeVisibility(&'ast Visibility), + + NodeInlinedItem(&'ast InlinedItem), } /// Represents an entry and its parent NodeID. @@ -120,6 +121,8 @@ impl<'ast> MapEntry<'ast> { NodeLifetime(n) => EntryLifetime(p, n), NodeTyParam(n) => EntryTyParam(p, n), NodeVisibility(n) => EntryVisibility(p, n), + + NodeInlinedItem(n) => RootInlinedParent(n), } } @@ -168,6 +171,7 @@ impl<'ast> MapEntry<'ast> { EntryLifetime(_, n) => NodeLifetime(n), EntryTyParam(_, n) => NodeTyParam(n), EntryVisibility(_, n) => NodeVisibility(n), + RootInlinedParent(n) => NodeInlinedItem(n), _ => return None }) } @@ -252,18 +256,36 @@ impl<'ast> Map<'ast> { let map = self.map.borrow(); let mut id = id0; if !self.is_inlined_node_id(id) { + let mut last_expr = None; loop { match map[id.as_usize()] { EntryItem(_, item) => { assert_eq!(id, item.id); 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 + // (Note that trait items don't currently have + // their own dep node, so there's also just one + // HirBody node for all the items) + if self.is_body(last_id, item) { + return DepNode::HirBody(def_id); + } + } return DepNode::Hir(def_id); } - EntryImplItem(..) => { + EntryImplItem(_, 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 + if self.is_impl_item_body(last_id, item) { + return DepNode::HirBody(def_id); + } + } return DepNode::Hir(def_id); } @@ -271,7 +293,6 @@ impl<'ast> Map<'ast> { EntryTraitItem(p, _) | EntryVariant(p, _) | EntryField(p, _) | - EntryExpr(p, _) | EntryStmt(p, _) | EntryTy(p, _) | EntryTraitRef(p, _) | @@ -284,6 +305,11 @@ impl<'ast> Map<'ast> { EntryVisibility(p, _) => id = p, + EntryExpr(p, _) => { + last_expr = Some(id); + id = p; + } + RootCrate => return DepNode::Krate, @@ -328,12 +354,8 @@ impl<'ast> Map<'ast> { EntryVisibility(p, _) => id = p, - RootInlinedParent(parent) => match *parent { - InlinedItem::Item(def_id, _) | - InlinedItem::TraitItem(def_id, _) | - InlinedItem::ImplItem(def_id, _) => - return DepNode::MetaData(def_id) - }, + RootInlinedParent(parent) => + return DepNode::MetaData(parent.def_id), RootCrate => bug!("node {} has crate ancestor but is inlined", id0), @@ -345,6 +367,29 @@ impl<'ast> Map<'ast> { } } + fn is_body(&self, node_id: NodeId, item: &Item) -> bool { + match item.node { + ItemFn(_, _, _, _, _, body) => body.node_id() == node_id, + // Since trait items currently don't get their own dep nodes, + // we check here whether node_id is the body of any of the items. + // If they get their own dep nodes, this can go away + ItemTrait(_, _, _, ref trait_items) => { + trait_items.iter().any(|trait_item| { match trait_item.node { + MethodTraitItem(_, Some(body)) => body.node_id() == node_id, + _ => false + }}) + } + _ => false + } + } + + fn is_impl_item_body(&self, node_id: NodeId, item: &ImplItem) -> bool { + match item.node { + ImplItemKind::Method(_, body) => body.node_id() == node_id, + _ => false + } + } + pub fn num_local_def_ids(&self) -> usize { self.definitions.borrow().len() } @@ -556,8 +601,7 @@ impl<'ast> Map<'ast> { pub fn get_parent_did(&self, id: NodeId) -> DefId { let parent = self.get_parent(id); match self.find_entry(parent) { - Some(RootInlinedParent(&II::TraitItem(did, _))) | - Some(RootInlinedParent(&II::ImplItem(did, _))) => did, + Some(RootInlinedParent(ii)) => ii.def_id, _ => self.local_def_id(parent) } } @@ -655,6 +699,10 @@ 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) { @@ -958,6 +1006,8 @@ impl<'a> NodePrinter for pprust::State<'a> { // printing. NodeLocal(_) => bug!("cannot print isolated Local"), NodeStructCtor(_) => bug!("cannot print isolated StructCtor"), + + NodeInlinedItem(_) => bug!("cannot print inlined item"), } } } @@ -1071,6 +1121,9 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { Some(NodeVisibility(ref vis)) => { format!("visibility {:?}{}", vis, id_str) } + Some(NodeInlinedItem(_)) => { + format!("inlined item {}", id_str) + } None => { format!("unknown node{}", id_str) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index d494299a3c388..4fd8f96ba046a 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -33,6 +33,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 syntax_pos::{mk_sp, Span, ExpnId, DUMMY_SP}; use syntax::codemap::{self, respan, Spanned}; @@ -428,6 +429,7 @@ pub struct Crate { pub items: BTreeMap, pub impl_items: BTreeMap, + pub exprs: FnvHashMap, } impl Crate { @@ -458,6 +460,10 @@ impl Crate { visitor.visit_impl_item(impl_item); } } + + pub fn expr(&self, id: ExprId) -> &Expr { + &self.exprs[&id] + } } /// A macro definition, in this crate or imported from another. @@ -846,6 +852,15 @@ pub enum UnsafeSource { UserProvided, } +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ExprId(NodeId); + +impl ExprId { + pub fn node_id(self) -> NodeId { + self.0 + } +} + /// An expression #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] pub struct Expr { @@ -855,6 +870,12 @@ 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)) @@ -914,7 +935,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, P, Span), + ExprClosure(CaptureClause, P, ExprId, Span), /// A block (`{ ... }`) ExprBlock(P), @@ -1068,7 +1089,7 @@ pub enum TraitItem_ { /// must contain a value) ConstTraitItem(P, Option>), /// A method with an optional body - MethodTraitItem(MethodSig, Option>), + MethodTraitItem(MethodSig, Option), /// An associated type with (possibly empty) bounds and optional concrete /// type TypeTraitItem(TyParamBounds, Option>), @@ -1101,7 +1122,7 @@ pub enum ImplItemKind { /// of the expression Const(P, P), /// A method implementation with the given signature and body - Method(MethodSig, P), + Method(MethodSig, ExprId), /// An associated type Type(P), } @@ -1546,7 +1567,7 @@ pub enum Item_ { /// A `const` item ItemConst(P, P), /// A function declaration - ItemFn(P, Unsafety, Constness, Abi, Generics, P), + ItemFn(P, Unsafety, Constness, Abi, Generics, ExprId), /// A module ItemMod(Mod), /// An external module diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 31a8539119398..74920b1328076 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -644,6 +644,15 @@ impl<'a> State<'a> { } } + pub fn print_expr_id(&mut self, expr_id: &hir::ExprId) -> io::Result<()> { + if let Some(krate) = self.krate { + let expr = &krate.exprs[expr_id]; + self.print_expr(expr) + } else { + Ok(()) + } + } + /// Pretty-print an item pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> { self.hardbreak_if_not_bol()?; @@ -729,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(&body)?; + self.print_expr_id(body)?; } hir::ItemMod(ref _mod) => { self.head(&visibility_qualified(&item.vis, "mod"))?; @@ -1020,7 +1029,7 @@ impl<'a> State<'a> { self.nbsp()?; self.end()?; // need to close a box self.end()?; // need to close a box - self.print_expr(body)?; + self.print_expr_id(body)?; } else { word(&mut self.s, ";")?; } @@ -1065,7 +1074,7 @@ impl<'a> State<'a> { self.nbsp()?; self.end()?; // need to close a box self.end()?; // need to close a box - self.print_expr(body)?; + self.print_expr_id(body)?; } hir::ImplItemKind::Type(ref ty) => { self.print_associated_type(ii.name, None, Some(ty))?; @@ -1432,7 +1441,7 @@ impl<'a> State<'a> { space(&mut self.s)?; // this is a bare expression - self.print_expr(body)?; + self.print_expr_id(body)?; self.end()?; // need to close a box // a box will be closed by print_expr, but we didn't want an overall diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 41c8d413486dc..fba4f35074dbc 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -719,10 +719,10 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { } } - fn visit_ids(&mut self, f: F) - where F: FnOnce(&mut IdVisitor) + fn visit_ids<'b, F: 'b>(&'b mut self, f: F) + where F: FnOnce(&mut IdVisitor<'b, 'a, 'tcx>) { - let mut v = IdVisitor { + let mut v = IdVisitor::<'b, 'a, 'tcx> { cx: self }; f(&mut v); @@ -791,8 +791,8 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { /// Because lints are scoped lexically, we want to walk nested /// items in the context of the outer item, so enable /// deep-walking. - fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> { - Some(&self.tcx.map) + fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'tcx> { + hir_visit::NestedVisitorMap::All(&self.tcx.map) } fn visit_item(&mut self, it: &'tcx hir::Item) { @@ -835,9 +835,10 @@ 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: &'tcx hir::Expr, span: Span, id: ast::NodeId) { + body_id: hir::ExprId, span: Span, id: ast::NodeId) { + let body = self.tcx.map.expr(body_id); run_lints!(self, check_fn, late_passes, fk, decl, body, span, id); - hir_visit::walk_fn(self, 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); } @@ -1107,7 +1108,11 @@ struct IdVisitor<'a, 'b: 'a, 'tcx: 'a+'b> { } // Output any lints that were previously added to the session. -impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> { +impl<'a, 'b, 'tcx> hir_visit::Visitor<'tcx> for IdVisitor<'a, 'b, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'tcx> { + hir_visit::NestedVisitorMap::OnlyBodies(&self.cx.tcx.map) + } + fn visit_id(&mut self, id: ast::NodeId) { if let Some(lints) = self.cx.sess().lints.borrow_mut().remove(&id) { debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints); @@ -1117,12 +1122,12 @@ impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> { } } - fn visit_trait_item(&mut self, _ti: &hir::TraitItem) { + fn visit_trait_item(&mut self, _ti: &'tcx hir::TraitItem) { // Do not recurse into trait or impl items automatically. These are // processed separately by calling hir_visit::walk_trait_item() } - fn visit_impl_item(&mut self, _ii: &hir::ImplItem) { + fn visit_impl_item(&mut self, _ii: &'tcx hir::ImplItem) { // See visit_trait_item() } } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 0867e75b9ca80..d055506a38226 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -137,18 +137,96 @@ pub struct NativeLibrary { /// part of the AST that we parse from a file, but it becomes part of the tree /// that we trans. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum InlinedItem { - Item(DefId /* def-id in source crate */, P), - TraitItem(DefId /* impl id */, P), - ImplItem(DefId /* impl id */, P) +pub struct InlinedItem { + pub def_id: DefId, + pub body: P, + pub const_fn_args: Vec>, +} + +/// A borrowed version of `hir::InlinedItem`. This is what's encoded when saving +/// a crate; it then gets read as an InlinedItem. +#[derive(Clone, PartialEq, Eq, RustcEncodable, Hash, Debug)] +pub struct InlinedItemRef<'a> { + pub def_id: DefId, + pub body: &'a hir::Expr, + pub const_fn_args: Vec>, +} + +fn get_fn_args(decl: &hir::FnDecl) -> Vec> { + decl.inputs.iter().map(|arg| match arg.pat.node { + hir::PatKind::Binding(_, def_id, _, _) => Some(def_id), + _ => None + }).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 { + hir::ItemFn(ref decl, _, _, _, _, body_id) => + (tcx.map.expr(body_id), get_fn_args(decl)), + hir::ItemConst(_, ref body) => (&**body, Vec::new()), + _ => bug!("InlinedItemRef::from_item wrong kind") + }; + InlinedItemRef { + def_id: def_id, + body: body, + 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::ConstTraitItem(_, Some(ref body)) => + (&**body, Vec::new()), + hir::ConstTraitItem(_, None) => { + bug!("InlinedItemRef::from_trait_item called for const without body") + }, + _ => bug!("InlinedItemRef::from_trait_item wrong kind") + }; + InlinedItemRef { + def_id: def_id, + body: body, + 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 { + 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()), + _ => bug!("InlinedItemRef::from_impl_item wrong kind") + }; + InlinedItemRef { + def_id: def_id, + body: body, + const_fn_args: args + } + } + + pub fn visit(&self, visitor: &mut V) + where V: Visitor<'a> + { + visitor.visit_expr(&self.body); + } } -/// A borrowed version of `hir::InlinedItem`. -#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, Hash, Debug)] -pub enum InlinedItemRef<'a> { - Item(DefId, &'a hir::Item), - TraitItem(DefId, &'a hir::TraitItem), - ImplItem(DefId, &'a hir::ImplItem) +impl InlinedItem { + pub fn visit<'ast,V>(&'ast self, visitor: &mut V) + where V: Visitor<'ast> + { + visitor.visit_expr(&self.body); + } } pub enum LoadedMacro { @@ -292,18 +370,6 @@ pub trait CrateStore<'tcx> { fn metadata_encoding_version(&self) -> &[u8]; } -impl InlinedItem { - pub fn visit<'ast,V>(&'ast self, visitor: &mut V) - where V: Visitor<'ast> - { - match *self { - InlinedItem::Item(_, ref i) => visitor.visit_item(&i), - InlinedItem::TraitItem(_, ref ti) => visitor.visit_trait_item(ti), - InlinedItem::ImplItem(_, ref ii) => visitor.visit_impl_item(ii), - } - } -} - // FIXME: find a better place for this? pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option) { let mut err_count = 0; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 1ec3d0db8e0aa..f7a34c43cccbd 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -193,6 +193,10 @@ fn build_nodeid_to_index(decl: Option<&hir::FnDecl>, let mut formals = Formals { entry: entry, index: index }; 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") + } + fn visit_pat(&mut self, p: &hir::Pat) { self.index.entry(p.id).or_insert(vec![]).push(self.entry); intravisit::walk_pat(self, p) diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 618e2b05f13b7..1bf6b837fd998 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -15,7 +15,7 @@ use dep_graph::DepNode; use hir::map as ast_map; use hir::{self, PatKind}; -use hir::intravisit::{self, Visitor}; +use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir::itemlikevisit::ItemLikeVisitor; use middle::privacy; @@ -175,7 +175,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } } - fn visit_node(&mut self, node: &ast_map::Node) { + fn visit_node(&mut self, node: &ast_map::Node<'tcx>) { let had_extern_repr = self.struct_has_extern_repr; self.struct_has_extern_repr = false; let had_inherited_pub_visibility = self.inherited_pub_visibility; @@ -220,9 +220,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } } -impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { +impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } - fn visit_variant_data(&mut self, def: &hir::VariantData, _: ast::Name, + fn visit_variant_data(&mut self, def: &'tcx hir::VariantData, _: ast::Name, _: &hir::Generics, _: ast::NodeId, _: syntax_pos::Span) { let has_extern_repr = self.struct_has_extern_repr; let inherited_pub_visibility = self.inherited_pub_visibility; @@ -234,7 +237,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { intravisit::walk_struct_def(self, def); } - fn visit_expr(&mut self, expr: &hir::Expr) { + fn visit_expr(&mut self, expr: &'tcx hir::Expr) { match expr.node { hir::ExprPath(ref qpath @ hir::QPath::TypeRelative(..)) => { let def = self.tcx.tables().qpath_def(qpath, expr.id); @@ -255,7 +258,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { intravisit::walk_expr(self, expr); } - fn visit_arm(&mut self, arm: &hir::Arm) { + fn visit_arm(&mut self, arm: &'tcx hir::Arm) { if arm.pats.len() == 1 { let variants = arm.pats[0].necessary_variants(); @@ -271,7 +274,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { } } - fn visit_pat(&mut self, pat: &hir::Pat) { + fn visit_pat(&mut self, pat: &'tcx hir::Pat) { match pat.node { PatKind::Struct(hir::QPath::Resolved(_, ref path), ref fields, _) => { self.handle_field_pattern_match(pat, path.def, fields); @@ -288,7 +291,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { self.ignore_non_const_paths = false; } - fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) { + fn visit_path(&mut self, path: &'tcx hir::Path, id: ast::NodeId) { self.handle_definition(id, path.def); intravisit::walk_path(self, path); } @@ -507,8 +510,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { /// on inner functions when the outer function is already getting /// an error. We could do this also by checking the parents, but /// this is how the code is setup and it seems harmless enough. - fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> { - Some(&self.tcx.map) + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::All(&self.tcx.map) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -562,12 +565,12 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { } intravisit::walk_expr(self, expr) } - hir::ImplItemKind::Method(_, ref body) => { + 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"); } - intravisit::walk_expr(self, body) + self.visit_body(body_id) } hir::ImplItemKind::Type(..) => {} } @@ -576,10 +579,12 @@ 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::ConstTraitItem(_, Some(ref body))| - hir::MethodTraitItem(_, Some(ref body)) => { + hir::ConstTraitItem(_, Some(ref body)) => { intravisit::walk_expr(self, body) } + hir::MethodTraitItem(_, Some(body_id)) => { + self.visit_body(body_id) + } hir::ConstTraitItem(_, None) | hir::MethodTraitItem(_, None) | hir::TypeTraitItem(..) => {} diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 1313a3504c0bd..2ec7aa4c4d903 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -21,7 +21,7 @@ use syntax::ast; use syntax_pos::Span; use hir::{self, PatKind}; use hir::def::Def; -use hir::intravisit::{self, FnKind, Visitor}; +use hir::intravisit::{self, FnKind, Visitor, NestedVisitorMap}; #[derive(Copy, Clone)] struct UnsafeContext { @@ -92,9 +92,13 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> { } } -impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { - fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v hir::FnDecl, - block: &'v hir::Expr, span: Span, id: ast::NodeId) { +impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + + fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl, + body_id: hir::ExprId, span: Span, id: ast::NodeId) { let (is_item_fn, is_unsafe_fn) = match fn_kind { FnKind::ItemFn(_, _, unsafety, ..) => @@ -111,12 +115,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { self.unsafe_context = UnsafeContext::new(SafeContext) } - intravisit::walk_fn(self, fn_kind, fn_decl, block, span, id); + intravisit::walk_fn(self, fn_kind, fn_decl, body_id, span, id); self.unsafe_context = old_unsafe_context } - fn visit_block(&mut self, block: &hir::Block) { + fn visit_block(&mut self, block: &'tcx hir::Block) { let old_unsafe_context = self.unsafe_context; match block.rules { hir::UnsafeBlock(source) => { @@ -155,7 +159,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { self.unsafe_context = old_unsafe_context } - fn visit_expr(&mut self, expr: &hir::Expr) { + fn visit_expr(&mut self, expr: &'tcx hir::Expr) { match expr.node { hir::ExprMethodCall(..) => { let method_call = MethodCall::expr(expr.id); @@ -212,7 +216,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { intravisit::walk_expr(self, expr); } - fn visit_pat(&mut self, pat: &hir::Pat) { + fn visit_pat(&mut self, pat: &'tcx hir::Pat) { if let PatKind::Struct(_, ref fields, _) = pat.node { if let ty::TyAdt(adt, ..) = self.tcx.tables().pat_ty(pat).sty { if adt.is_union() { diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 65aedae347a8d..e927843a984b8 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -47,6 +47,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> { find_item(item, self, at_root); } + fn visit_impl_item(&mut self, _impl_item: &'tcx ImplItem) { // entry fn is never an impl item } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 0014d17abb7f2..6896c69d7db92 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -19,7 +19,7 @@ use ty::layout::{LayoutError, Pointer, SizeSkeleton}; use syntax::abi::Abi::RustIntrinsic; use syntax::ast; use syntax_pos::Span; -use hir::intravisit::{self, Visitor, FnKind}; +use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; use hir; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { @@ -34,7 +34,7 @@ struct ItemVisitor<'a, 'tcx: 'a> { } impl<'a, 'tcx> ItemVisitor<'a, 'tcx> { - fn visit_const(&mut self, item_id: ast::NodeId, expr: &hir::Expr) { + fn visit_const(&mut self, item_id: ast::NodeId, expr: &'tcx hir::Expr) { 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 { @@ -116,9 +116,13 @@ impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> { } } -impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> { +impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + // const, static and N in [T; N]. - fn visit_expr(&mut self, expr: &hir::Expr) { + fn visit_expr(&mut self, expr: &'tcx hir::Expr) { self.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| { let mut visitor = ExprVisitor { infcx: &infcx @@ -127,7 +131,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> { }); } - fn visit_trait_item(&mut self, item: &hir::TraitItem) { + fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) { if let hir::ConstTraitItem(_, Some(ref expr)) = item.node { self.visit_const(item.id, expr); } else { @@ -135,7 +139,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> { } } - fn visit_impl_item(&mut self, item: &hir::ImplItem) { + 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); } else { @@ -143,8 +147,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> { } } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl, - b: &'v hir::Expr, s: Span, id: ast::NodeId) { + fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, + b: hir::ExprId, s: Span, id: ast::NodeId) { if let FnKind::Closure(..) = fk { span_bug!(s, "intrinsicck: closure outside of function") } @@ -158,8 +162,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> { } } -impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for ExprVisitor<'a, 'gcx, 'tcx> { - fn visit_expr(&mut self, expr: &hir::Expr) { +impl<'a, 'gcx, 'tcx> Visitor<'gcx> for ExprVisitor<'a, 'gcx, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> { + NestedVisitorMap::OnlyBodies(&self.infcx.tcx.map) + } + + fn visit_expr(&mut self, expr: &'gcx hir::Expr) { let def = if let hir::ExprPath(ref qpath) = expr.node { self.infcx.tcx.tables().qpath_def(qpath, expr.id) } else { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index eb00238492ee1..445aed8f97d60 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -128,7 +128,7 @@ use syntax_pos::Span; use hir::Expr; use hir; use hir::print::{expr_to_string, block_to_string}; -use hir::intravisit::{self, Visitor, FnKind}; +use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; /// For use with `propagate_through_loop`. enum LoopKind<'a> { @@ -182,14 +182,18 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt) -> String { } } -impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> { - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl, - b: &'v hir::Expr, s: Span, id: NodeId) { +impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + + fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, + b: hir::ExprId, s: Span, id: NodeId) { visit_fn(self, fk, fd, b, s, id); } - fn visit_local(&mut self, l: &hir::Local) { visit_local(self, l); } - fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); } - fn visit_arm(&mut self, a: &hir::Arm) { visit_arm(self, a); } + fn visit_local(&mut self, l: &'tcx hir::Local) { visit_local(self, l); } + fn visit_expr(&mut self, ex: &'tcx Expr) { visit_expr(self, ex); } + fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); } } pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { @@ -348,28 +352,32 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> { } } -impl<'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> { - fn visit_fn(&mut self, _: FnKind<'v>, _: &'v hir::FnDecl, - _: &'v hir::Expr, _: Span, _: NodeId) { +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) + } + + 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: &hir::Local) { + fn visit_local(&mut self, l: &'tcx hir::Local) { check_local(self, l); } - fn visit_expr(&mut self, ex: &Expr) { + fn visit_expr(&mut self, ex: &'tcx Expr) { check_expr(self, ex); } - fn visit_arm(&mut self, a: &hir::Arm) { + fn visit_arm(&mut self, a: &'tcx hir::Arm) { check_arm(self, a); } } -fn visit_fn(ir: &mut IrMaps, - fk: FnKind, - decl: &hir::FnDecl, - body: &hir::Expr, - sp: Span, - id: ast::NodeId) { +fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>, + fk: FnKind<'tcx>, + decl: &'tcx hir::FnDecl, + body_id: hir::ExprId, + sp: Span, + id: ast::NodeId) { debug!("visit_fn"); // swap in a new set of IR maps for this function body: @@ -387,7 +395,7 @@ fn visit_fn(ir: &mut IrMaps, // gather up the various local variables, significant expressions, // and so forth: - intravisit::walk_fn(&mut fn_maps, fk, decl, body, sp, id); + intravisit::walk_fn(&mut fn_maps, fk, decl, body_id, sp, id); // Special nodes and variables: // - exit_ln represents the end of the fn, either by return or panic @@ -400,6 +408,8 @@ fn visit_fn(ir: &mut IrMaps, clean_exit_var: fn_maps.add_variable(CleanExit) }; + let body = ir.tcx.map.expr(body_id); + // compute liveness let mut lsets = Liveness::new(&mut fn_maps, specials); let entry_ln = lsets.compute(body); @@ -410,7 +420,7 @@ fn visit_fn(ir: &mut IrMaps, lsets.warn_about_unused_args(decl, entry_ln); } -fn visit_local(ir: &mut IrMaps, local: &hir::Local) { +fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) { local.pat.each_binding(|_, p_id, sp, path1| { debug!("adding local variable {}", p_id); let name = path1.node; @@ -423,7 +433,7 @@ fn visit_local(ir: &mut IrMaps, local: &hir::Local) { intravisit::walk_local(ir, local); } -fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) { +fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) { for pat in &arm.pats { pat.each_binding(|bm, p_id, sp, path1| { debug!("adding local variable {} from match with bm {:?}", @@ -439,7 +449,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) { intravisit::walk_arm(ir, arm); } -fn visit_expr(ir: &mut IrMaps, expr: &Expr) { +fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) { match expr.node { // live nodes required for uses or definitions of variables: hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { @@ -923,7 +933,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(&e, succ) } - hir::ExprClosure(.., ref blk, _) => { + hir::ExprClosure(.., blk_id, _) => { debug!("{} is an ExprClosure", expr_to_string(expr)); @@ -932,7 +942,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, 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. @@ -1354,7 +1364,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // _______________________________________________________________________ // Checking for error conditions -fn check_local(this: &mut Liveness, local: &hir::Local) { +fn check_local<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, local: &'tcx hir::Local) { match local.init { Some(_) => { this.warn_about_unused_or_dead_vars_in_pat(&local.pat); @@ -1369,7 +1379,7 @@ fn check_local(this: &mut Liveness, local: &hir::Local) { intravisit::walk_local(this, local); } -fn check_arm(this: &mut Liveness, arm: &hir::Arm) { +fn check_arm<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, arm: &'tcx hir::Arm) { // only consider the first pattern; any later patterns must have // the same bindings, and we also consider the first pattern to be // the "authoritative" set of ids @@ -1379,7 +1389,7 @@ fn check_arm(this: &mut Liveness, arm: &hir::Arm) { intravisit::walk_arm(this, arm); } -fn check_expr(this: &mut Liveness, expr: &Expr) { +fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) { match expr.node { hir::ExprAssign(ref l, _) => { this.check_lvalue(&l); @@ -1469,7 +1479,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } } - fn check_lvalue(&mut self, expr: &Expr) { + fn check_lvalue(&mut self, expr: &'tcx Expr) { match expr.node { hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { if let Def::Local(def_id) = path.def { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 8d3e734f8c33f..4c3b102e54039 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(.., ref body, _) => body.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 b17d41e0fa544..9798b2d587dbf 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -28,7 +28,7 @@ use syntax::abi::Abi; use syntax::ast; use syntax::attr; use hir; -use hir::intravisit::Visitor; +use hir::intravisit::{Visitor, NestedVisitorMap}; use hir::itemlikevisit::ItemLikeVisitor; use hir::intravisit; @@ -88,8 +88,12 @@ struct ReachableContext<'a, 'tcx: 'a> { any_library: bool, } -impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { - fn visit_expr(&mut self, expr: &hir::Expr) { +impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + + fn visit_expr(&mut self, expr: &'tcx hir::Expr) { let def = match expr.node { hir::ExprPath(ref qpath) => { Some(self.tcx.tables().qpath_def(qpath, expr.id)) @@ -216,7 +220,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } - fn propagate_node(&mut self, node: &ast_map::Node, + fn propagate_node(&mut self, node: &ast_map::Node<'tcx>, search_item: ast::NodeId) { if !self.any_library { // If we are building an executable, only explicitly extern @@ -244,9 +248,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { match *node { ast_map::NodeItem(item) => { match item.node { - hir::ItemFn(.., ref body) => { + hir::ItemFn(.., body) => { if item_might_be_inlined(&item) { - self.visit_expr(body); + self.visit_body(body); } } @@ -274,10 +278,12 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { hir::MethodTraitItem(_, None) => { // Keep going, nothing to get exported } - hir::ConstTraitItem(_, Some(ref body)) | - hir::MethodTraitItem(_, Some(ref body)) => { + hir::ConstTraitItem(_, Some(ref body)) => { self.visit_expr(body); } + hir::MethodTraitItem(_, Some(body_id)) => { + self.visit_body(body_id); + } hir::TypeTraitItem(..) => {} } } @@ -286,10 +292,10 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { hir::ImplItemKind::Const(_, ref expr) => { self.visit_expr(&expr); } - hir::ImplItemKind::Method(ref sig, ref 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_expr(body) + self.visit_body(body) } } hir::ImplItemKind::Type(_) => {} diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 0dbde2d21caf5..05fa619ce41e4 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -31,7 +31,7 @@ use syntax::ast::{self, NodeId}; use syntax_pos::Span; use hir; -use hir::intravisit::{self, Visitor, FnKind}; +use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local}; #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, @@ -302,7 +302,7 @@ pub struct Context { parent: CodeExtent } -struct RegionResolutionVisitor<'a> { +struct RegionResolutionVisitor<'ast: 'a, 'a> { sess: &'a Session, // Generated maps: @@ -310,6 +310,8 @@ struct RegionResolutionVisitor<'a> { cx: Context, + map: &'a ast_map::Map<'ast>, + /// `terminating_scopes` is a set containing the ids of each /// statement, or conditional/repeating expression. These scopes /// are calling "terminating scopes" because, when attempting to @@ -660,7 +662,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor, } } -fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &hir::Block) { +fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk: &'tcx hir::Block) { debug!("resolve_block(blk.id={:?})", blk.id); let prev_cx = visitor.cx; @@ -731,7 +733,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &hir::Block) { visitor.cx = prev_cx; } -fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) { +fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, arm: &'tcx hir::Arm) { visitor.terminating_scopes.insert(arm.body.id); if let Some(ref expr) = arm.guard { @@ -741,7 +743,7 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) { intravisit::walk_arm(visitor, arm); } -fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) { +fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, pat: &'tcx hir::Pat) { visitor.new_node_extent(pat.id); // If this is a binding then record the lifetime of that binding. @@ -752,7 +754,7 @@ fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) { intravisit::walk_pat(visitor, pat); } -fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) { +fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt: &'tcx hir::Stmt) { let stmt_id = stmt.node.id(); debug!("resolve_stmt(stmt.id={:?})", stmt_id); @@ -770,7 +772,7 @@ fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) { visitor.cx.parent = prev_parent; } -fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &hir::Expr) { +fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr: &'tcx hir::Expr) { debug!("resolve_expr(expr.id={:?})", expr.id); let expr_extent = visitor.new_node_extent_with_dtor(expr.id); @@ -848,7 +850,8 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &hir::Expr) { visitor.cx = prev_cx; } -fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) { +fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, + local: &'tcx hir::Local) { debug!("resolve_local(local.id={:?},local.init={:?})", local.id,local.init.is_some()); @@ -1063,7 +1066,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) { } } -fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &hir::Item) { +fn resolve_item<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, item: &'tcx hir::Item) { // Items create a new outer block scope as far as we're concerned. let prev_cx = visitor.cx; let prev_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet()); @@ -1078,38 +1081,38 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &hir::Item) { visitor.terminating_scopes = prev_ts; } -fn resolve_fn(visitor: &mut RegionResolutionVisitor, - kind: FnKind, - decl: &hir::FnDecl, - body: &hir::Expr, - sp: Span, - id: ast::NodeId) { +fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, + kind: FnKind<'tcx>, + decl: &'tcx hir::FnDecl, + body_id: hir::ExprId, + sp: Span, + id: ast::NodeId) { debug!("region::resolve_fn(id={:?}, \ span={:?}, \ body.id={:?}, \ cx.parent={:?})", id, visitor.sess.codemap().span_to_string(sp), - body.id, + body_id, visitor.cx.parent); visitor.cx.parent = visitor.new_code_extent( - CodeExtentData::CallSiteScope { fn_id: id, body_id: body.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 }); + 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, 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); + 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), + root_id: Some(body_id.node_id()), parent: ROOT_CODE_EXTENT, var_parent: fn_decl_scope, }; @@ -1119,18 +1122,18 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor, // The body of the every fn is a root scope. visitor.cx = Context { - root_id: Some(body.id), + root_id: Some(body_id.node_id()), parent: fn_decl_scope, var_parent: fn_decl_scope }; - visitor.visit_expr(body); + visitor.visit_body(body_id); // Restore context we had at the start. visitor.cx = outer_cx; visitor.terminating_scopes = outer_ts; } -impl<'a> RegionResolutionVisitor<'a> { +impl<'ast, 'a> RegionResolutionVisitor<'ast, 'a> { /// Records the current parent (if any) as the parent of `child_scope`. fn new_code_extent(&mut self, child_scope: CodeExtentData) -> CodeExtent { self.region_maps.intern_code_extent(child_scope, self.cx.parent) @@ -1166,42 +1169,46 @@ impl<'a> RegionResolutionVisitor<'a> { } } -impl<'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> { - fn visit_block(&mut self, b: &Block) { +impl<'ast, 'a> Visitor<'ast> for RegionResolutionVisitor<'ast, 'a> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { + NestedVisitorMap::OnlyBodies(&self.map) + } + + fn visit_block(&mut self, b: &'ast Block) { resolve_block(self, b); } - fn visit_item(&mut self, i: &Item) { + fn visit_item(&mut self, i: &'ast Item) { resolve_item(self, i); } - fn visit_impl_item(&mut self, ii: &hir::ImplItem) { + fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) { intravisit::walk_impl_item(self, ii); self.create_item_scope_if_needed(ii.id); } - fn visit_trait_item(&mut self, ti: &hir::TraitItem) { + fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) { intravisit::walk_trait_item(self, ti); self.create_item_scope_if_needed(ti.id); } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, - b: &'v Expr, s: Span, n: NodeId) { + fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl, + b: hir::ExprId, s: Span, n: NodeId) { resolve_fn(self, fk, fd, b, s, n); } - fn visit_arm(&mut self, a: &Arm) { + fn visit_arm(&mut self, a: &'ast Arm) { resolve_arm(self, a); } - fn visit_pat(&mut self, p: &Pat) { + fn visit_pat(&mut self, p: &'ast Pat) { resolve_pat(self, p); } - fn visit_stmt(&mut self, s: &Stmt) { + fn visit_stmt(&mut self, s: &'ast Stmt) { resolve_stmt(self, s); } - fn visit_expr(&mut self, ex: &Expr) { + fn visit_expr(&mut self, ex: &'ast Expr) { resolve_expr(self, ex); } - fn visit_local(&mut self, l: &Local) { + fn visit_local(&mut self, l: &'ast Local) { resolve_local(self, l); } } @@ -1228,6 +1235,7 @@ pub fn resolve_crate(sess: &Session, map: &ast_map::Map) -> RegionMaps { let mut visitor = RegionResolutionVisitor { sess: sess, region_maps: &maps, + map: map, cx: Context { root_id: None, parent: ROOT_CODE_EXTENT, diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index d07062f98a9d1..c5b03a4a32add 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -34,7 +34,7 @@ use util::nodemap::NodeMap; use rustc_data_structures::fx::FxHashSet; use hir; use hir::print::lifetime_to_string; -use hir::intravisit::{self, Visitor, FnKind}; +use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] pub enum DefRegion { @@ -132,8 +132,8 @@ pub fn krate(sess: &Session, impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // Override the nested functions -- lifetimes follow lexical scope, // so it's convenient to walk the tree in lexical order. - fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> { - Some(&self.hir_map) + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::All(&self.hir_map) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -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: &'tcx hir::Expr, s: Span, fn_id: ast::NodeId) { + b: hir::ExprId, 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::Expr) { +fn extract_labels(ctxt: &mut LifetimeContext, b: hir::ExprId) { struct GatherLabels<'a> { sess: &'a Session, scope: Scope<'a>, @@ -419,10 +419,14 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: &hir::Expr) { scope: ctxt.scope, labels_in_fn: &mut ctxt.labels_in_fn, }; - gather.visit_expr(b); + gather.visit_expr(ctxt.hir_map.expr(b)); return; impl<'v, 'a> Visitor<'v> for GatherLabels<'a> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { + NestedVisitorMap::None + } + fn visit_expr(&mut self, ex: &'v hir::Expr) { // do not recurse into closures defined in the block // since they are treated as separate fns from the POV of @@ -497,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: &'tcx hir::Expr, + fb: hir::ExprId, _span: Span, fn_id: ast::NodeId) { match fk { @@ -518,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.id, s: self.scope }, - |_old_scope, this| this.visit_expr(fb)) + self.with(FnScope { fn_id: fn_id, body_id: fb.node_id(), s: self.scope }, + |_old_scope, this| this.visit_body(fb)) } // FIXME(#37666) this works around a limitation in the region inferencer @@ -938,6 +942,10 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap, } impl<'v> Visitor<'v> for ConstrainedCollector { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { + NestedVisitorMap::None + } + fn visit_ty(&mut self, ty: &'v hir::Ty) { match ty.node { hir::TyPath(hir::QPath::Resolved(Some(_), _)) | @@ -975,6 +983,10 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap, } impl<'v> Visitor<'v> for AllCollector { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { + NestedVisitorMap::None + } + fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { self.regions.insert(lifetime_ref.name); } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index f5e18e13465d8..f3890f1c3b7e3 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -30,8 +30,7 @@ use util::nodemap::{DefIdMap, FxHashSet, FxHashMap}; use hir; use hir::{Item, Generics, StructField, Variant}; -use hir::intravisit::{self, Visitor}; -use hir::itemlikevisit::DeepVisitor; +use hir::intravisit::{self, Visitor, NestedVisitorMap}; use std::mem::replace; use std::cmp::Ordering; @@ -234,8 +233,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { /// Because stability levels are scoped lexically, we want to walk /// nested items in the context of the outer item, so enable /// deep-walking. - fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> { - Some(&self.tcx.map) + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::All(&self.tcx.map) } fn visit_item(&mut self, i: &'tcx Item) { @@ -326,8 +325,12 @@ impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> { } } -impl<'a, 'tcx, 'v> Visitor<'v> for MissingStabilityAnnotations<'a, 'tcx> { - fn visit_item(&mut self, i: &Item) { +impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + + fn visit_item(&mut self, i: &'tcx Item) { match i.node { // Inherent impls and foreign modules serve only as containers for other items, // they don't have their own stability. They still can be annotated as unstable @@ -341,12 +344,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MissingStabilityAnnotations<'a, 'tcx> { intravisit::walk_item(self, i) } - fn visit_trait_item(&mut self, ti: &hir::TraitItem) { + fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) { self.check_missing_stability(ti.id, ti.span); intravisit::walk_trait_item(self, ti); } - fn visit_impl_item(&mut self, ii: &hir::ImplItem) { + fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { let impl_def_id = self.tcx.map.local_def_id(self.tcx.map.get_parent(ii.id)); if self.tcx.impl_trait_ref(impl_def_id).is_none() { self.check_missing_stability(ii.id, ii.span); @@ -354,22 +357,22 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MissingStabilityAnnotations<'a, 'tcx> { intravisit::walk_impl_item(self, ii); } - fn visit_variant(&mut self, var: &Variant, g: &Generics, item_id: NodeId) { + fn visit_variant(&mut self, var: &'tcx Variant, g: &'tcx Generics, item_id: NodeId) { self.check_missing_stability(var.node.data.id(), var.span); intravisit::walk_variant(self, var, g, item_id); } - fn visit_struct_field(&mut self, s: &StructField) { + fn visit_struct_field(&mut self, s: &'tcx StructField) { self.check_missing_stability(s.id, s.span); intravisit::walk_struct_field(self, s); } - fn visit_foreign_item(&mut self, i: &hir::ForeignItem) { + fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem) { self.check_missing_stability(i.id, i.span); intravisit::walk_foreign_item(self, i); } - fn visit_macro_def(&mut self, md: &hir::MacroDef) { + fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) { if md.imported_from.is_none() { self.check_missing_stability(md.id, md.span); } @@ -425,8 +428,7 @@ impl<'a, 'tcx> Index<'tcx> { /// features and possibly prints errors. pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let mut checker = Checker { tcx: tcx }; - tcx.visit_all_item_likes_in_krate(DepNode::StabilityCheck, - &mut DeepVisitor::new(&mut checker)); + tcx.visit_all_item_likes_in_krate(DepNode::StabilityCheck, &mut checker.as_deep_visitor()); } struct Checker<'a, 'tcx: 'a> { @@ -534,6 +536,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { + /// Because stability levels are scoped lexically, we want to walk + /// nested items in the context of the outer item, so enable + /// deep-walking. + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + fn visit_item(&mut self, item: &'tcx hir::Item) { match item.node { hir::ItemExternCrate(_) => { @@ -641,7 +650,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; missing.check_missing_stability(ast::CRATE_NODE_ID, krate.span); intravisit::walk_crate(&mut missing, krate); - krate.visit_all_item_likes(&mut DeepVisitor::new(&mut missing)); + krate.visit_all_item_likes(&mut missing.as_deep_visitor()); } let ref declared_lib_features = sess.features.borrow().declared_lib_features; diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 30690c099194f..c6df1497e681d 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -18,7 +18,7 @@ use rustc_back::PanicStrategy; use syntax::ast; use syntax::symbol::Symbol; use syntax_pos::Span; -use hir::intravisit::Visitor; +use hir::intravisit::{Visitor, NestedVisitorMap}; use hir::intravisit; use hir; @@ -125,6 +125,10 @@ impl<'a> Context<'a> { } impl<'a, 'v> Visitor<'v> for Context<'a> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { + NestedVisitorMap::None + } + fn visit_foreign_item(&mut self, i: &hir::ForeignItem) { if let Some(lang_item) = lang_items::extract(&i.attrs) { self.register(&lang_item.as_str(), i.span); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 844fc58cec37b..9a92e9e70feb4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1208,7 +1208,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.id)) + tcx.region_maps.call_site_extent(id, body.node_id())) } } } @@ -1227,9 +1227,9 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { // Use call-site for extent (unless this is a // trait method with no default; then fallback // to the method id). - let extent = if let Some(ref body) = *body { + 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) + 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) @@ -1243,14 +1243,14 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { } Some(ast_map::NodeItem(item)) => { match item.node { - hir::ItemFn(.., ref body) => { + hir::ItemFn(.., body_id) => { // We assume this is a function. let fn_def_id = tcx.map.local_def_id(id); tcx.construct_parameter_environment( item.span, fn_def_id, - tcx.region_maps.call_site_extent(id, body.id)) + tcx.region_maps.call_site_extent(id, body_id.node_id())) } hir::ItemEnum(..) | hir::ItemStruct(..) | @@ -1280,13 +1280,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { } Some(ast_map::NodeExpr(expr)) => { // This is a convenience to allow closures to work. - if let hir::ExprClosure(.., ref body, _) = expr.node { + if let hir::ExprClosure(.., body, _) = expr.node { let def_id = tcx.map.local_def_id(id); let base_def_id = tcx.closure_base_def_id(def_id); tcx.construct_parameter_environment( expr.span, base_def_id, - tcx.region_maps.call_site_extent(id, body.id)) + tcx.region_maps.call_site_extent(id, body.node_id())) } else { tcx.empty_parameter_environment() } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 8f2afa7f80822..5d59b58b847d9 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -30,7 +30,7 @@ use syntax_pos::Span; use rustc::hir; use rustc::hir::Expr; use rustc::hir::intravisit; -use rustc::hir::intravisit::Visitor; +use rustc::hir::intravisit::{Visitor, NestedVisitorMap}; use self::restrictions::RestrictionResult; @@ -520,8 +520,12 @@ struct StaticInitializerCtxt<'a, 'tcx: 'a> { item_id: ast::NodeId } -impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> { - fn visit_expr(&mut self, ex: &Expr) { +impl<'a, 'tcx> Visitor<'tcx> for StaticInitializerCtxt<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.bccx.tcx.map) + } + + fn visit_expr(&mut self, ex: &'tcx Expr) { if let hir::ExprAddrOf(mutbl, ref base) = ex.node { let param_env = ty::ParameterEnvironment::for_item(self.bccx.tcx, self.item_id); @@ -542,9 +546,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> { } } -pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, - item_id: ast::NodeId, - expr: &hir::Expr) { +pub fn gather_loans_in_static_initializer<'a, 'tcx>(bccx: &mut BorrowckCtxt<'a, 'tcx>, + item_id: ast::NodeId, + expr: &'tcx hir::Expr) { debug!("gather_loans_in_static_initializer(expr={:?})", expr); diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 5e54e333bb90c..34e91e6007464 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -47,7 +47,7 @@ use syntax_pos::{MultiSpan, Span}; use errors::DiagnosticBuilder; use rustc::hir; -use rustc::hir::intravisit::{self, Visitor, FnKind}; +use rustc::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; pub mod check_loans; @@ -62,9 +62,13 @@ pub struct LoanDataFlowOperator; pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>; -impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> { - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl, - b: &'v hir::Expr, s: Span, id: ast::NodeId) { +impl<'a, 'tcx> Visitor<'tcx> for BorrowckCtxt<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + + fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, + b: hir::ExprId, s: Span, id: ast::NodeId) { match fk { FnKind::ItemFn(..) | FnKind::Method(..) => { @@ -79,18 +83,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> { } } - fn visit_item(&mut self, item: &hir::Item) { + fn visit_item(&mut self, item: &'tcx hir::Item) { borrowck_item(self, item); } - fn visit_trait_item(&mut self, ti: &hir::TraitItem) { + fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) { if let hir::ConstTraitItem(_, Some(ref 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: &hir::ImplItem) { + 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); } @@ -131,7 +135,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { } } -fn borrowck_item(this: &mut BorrowckCtxt, item: &hir::Item) { +fn borrowck_item<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, item: &'tcx hir::Item) { // Gather loans for items. Note that we don't need // to check loans for single expressions. The check // loan step is intended for things that have a data @@ -154,15 +158,17 @@ pub struct AnalysisData<'a, 'tcx: 'a> { pub move_data: move_data::FlowedMoveData<'a, 'tcx>, } -fn borrowck_fn(this: &mut BorrowckCtxt, - fk: FnKind, - decl: &hir::FnDecl, - body: &hir::Expr, - sp: Span, - id: ast::NodeId, - attributes: &[ast::Attribute]) { +fn borrowck_fn<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, + fk: FnKind<'tcx>, + decl: &'tcx hir::FnDecl, + body_id: hir::ExprId, + sp: Span, + id: ast::NodeId, + attributes: &[ast::Attribute]) { debug!("borrowck_fn(id={})", id); + let body = this.tcx.map.expr(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) @@ -191,21 +197,21 @@ fn borrowck_fn(this: &mut BorrowckCtxt, decl, body); - intravisit::walk_fn(this, fk, decl, body, sp, id); + intravisit::walk_fn(this, fk, decl, body_id, sp, id); } fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, - fk: FnKind, - decl: &hir::FnDecl, + fk: FnKind<'tcx>, + decl: &'tcx hir::FnDecl, cfg: &cfg::CFG, - body: &hir::Expr, + body: &'tcx hir::Expr, 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); + let id_range = intravisit::compute_id_range_for_fn_body(fk, decl, body, sp, id, &tcx.map); let (all_loans, move_data) = gather_loans::gather_loans_in_fn(this, id, decl, body); @@ -241,7 +247,7 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, /// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer. pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - fn_parts: FnParts<'a>, + fn_parts: FnParts<'tcx>, cfg: &cfg::CFG) -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>) { @@ -257,11 +263,13 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>( } }; + let body = tcx.map.expr(fn_parts.body); + let dataflow_data = build_borrowck_dataflow_data(&mut bccx, fn_parts.kind, &fn_parts.decl, cfg, - &fn_parts.body, + body, fn_parts.span, fn_parts.id); @@ -407,8 +415,8 @@ pub fn closure_to_block(closure_id: ast::NodeId, tcx: TyCtxt) -> ast::NodeId { match tcx.map.get(closure_id) { hir_map::NodeExpr(expr) => match expr.node { - hir::ExprClosure(.., ref block, _) => { - block.id + hir::ExprClosure(.., body_id, _) => { + body_id.node_id() } _ => { bug!("encountered non-closure id: {}", closure_id) diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index b67c2c8ec9cdd..786b59e818da2 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -29,7 +29,7 @@ use rustc::ty::{self, TyCtxt}; use rustc_errors::DiagnosticBuilder; use rustc::hir::def::*; -use rustc::hir::intravisit::{self, Visitor, FnKind}; +use rustc::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; use rustc::hir::print::pat_to_string; use rustc::hir::{self, Pat, PatKind}; @@ -41,12 +41,16 @@ use syntax_pos::Span; struct OuterVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } -impl<'a, 'v, 'tcx> Visitor<'v> for OuterVisitor<'a, 'tcx> { - fn visit_expr(&mut self, _expr: &hir::Expr) { +impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::None + } + + fn visit_expr(&mut self, _expr: &'tcx hir::Expr) { return // const, static and N in [T; N] - shouldn't contain anything } - fn visit_trait_item(&mut self, item: &hir::TraitItem) { + fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) { if let hir::ConstTraitItem(..) = item.node { return // nothing worth match checking in a constant } else { @@ -54,7 +58,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for OuterVisitor<'a, 'tcx> { } } - fn visit_impl_item(&mut self, item: &hir::ImplItem) { + fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) { if let hir::ImplItemKind::Const(..) = item.node { return // nothing worth match checking in a constant } else { @@ -62,8 +66,8 @@ impl<'a, 'v, 'tcx> Visitor<'v> for OuterVisitor<'a, 'tcx> { } } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl, - b: &'v hir::Expr, s: Span, id: ast::NodeId) { + fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, + b: hir::ExprId, s: Span, id: ast::NodeId) { if let FnKind::Closure(..) = fk { span_bug!(s, "check_match: closure outside of function") } @@ -90,8 +94,12 @@ struct MatchVisitor<'a, 'tcx: 'a> { param_env: &'a ty::ParameterEnvironment<'tcx> } -impl<'a, 'tcx, 'v> Visitor<'v> for MatchVisitor<'a, 'tcx> { - fn visit_expr(&mut self, ex: &hir::Expr) { +impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + + fn visit_expr(&mut self, ex: &'tcx hir::Expr) { intravisit::walk_expr(self, ex); match ex.node { @@ -102,7 +110,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchVisitor<'a, 'tcx> { } } - fn visit_local(&mut self, loc: &hir::Local) { + fn visit_local(&mut self, loc: &'tcx hir::Local) { intravisit::walk_local(self, loc); self.check_irrefutable(&loc.pat, false); @@ -111,8 +119,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchVisitor<'a, 'tcx> { self.check_patterns(false, slice::ref_slice(&loc.pat)); } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl, - b: &'v hir::Expr, s: Span, n: ast::NodeId) { + fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, + b: hir::ExprId, s: Span, n: ast::NodeId) { intravisit::walk_fn(self, fk, fd, b, s, n); for input in &fd.inputs { @@ -557,6 +565,10 @@ struct AtBindingPatternVisitor<'a, 'b:'a, 'tcx:'b> { } impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { + NestedVisitorMap::None + } + fn visit_pat(&mut self, pat: &Pat) { match pat.node { PatKind::Binding(.., ref subpat) => { diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 053d3072ddf52..9fcab1239899f 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -33,7 +33,6 @@ use graphviz::IntoCow; use syntax::ast; use rustc::hir::{Expr, PatKind}; use rustc::hir; -use rustc::hir::intravisit::FnKind; use syntax::ptr::P; use syntax::codemap; use syntax::attr::IntType; @@ -103,14 +102,16 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, _ => None }, Some(ast_map::NodeTraitItem(ti)) => match ti.node { - hir::ConstTraitItem(..) => { + hir::ConstTraitItem(ref ty, ref expr_option) => { 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); - resolve_trait_associated_const(tcx, ti, trait_id, substs) + let default_value = expr_option.as_ref() + .map(|expr| (&**expr, 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 // expression that generates the obligation, we could @@ -141,33 +142,31 @@ 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::Item(_, ref item), _)) => match item.node { - hir::ItemConst(ref ty, ref const_expr) => { - Some((&**const_expr, tcx.ast_ty_to_prim_ty(ty))) - }, - _ => None - }, - Some((&InlinedItem::TraitItem(trait_id, ref ti), _)) => match ti.node { - hir::ConstTraitItem(..) => { + Some((&InlinedItem { body: ref const_expr, .. }, _)) => { + Some((&**const_expr, Some(tcx.sess.cstore.item_type(tcx, def_id)))) + } + _ => None + }; + let expr_ty = match tcx.sess.cstore.describe_def(def_id) { + Some(Def::AssociatedConst(_)) => { + let trait_id = tcx.sess.cstore.trait_of_item(def_id); + // As mentioned in the comments above for in-crate + // constants, we only try to find the expression for a + // trait-associated const if the caller gives us the + // substitutions for the reference to it. + if let Some(trait_id) = trait_id { used_substs = true; + if let Some(substs) = substs { - // As mentioned in the comments above for in-crate - // constants, we only try to find the expression for - // a trait-associated const if the caller gives us - // the substitutions for the reference to it. - resolve_trait_associated_const(tcx, ti, trait_id, substs) + resolve_trait_associated_const(tcx, def_id, expr_ty, trait_id, substs) } else { None } + } else { + expr_ty } - _ => None - }, - Some((&InlinedItem::ImplItem(_, ref ii), _)) => match ii.node { - hir::ImplItemKind::Const(ref ty, ref expr) => { - Some((&**expr, tcx.ast_ty_to_prim_ty(ty))) - }, - _ => None }, + Some(Def::Const(..)) => expr_ty, _ => None }; // If we used the substitutions, particularly to choose an impl @@ -196,24 +195,29 @@ fn inline_const_fn_from_external_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return None; } - let fn_id = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) { - Some((&InlinedItem::Item(_, ref item), _)) => Some(item.id), - Some((&InlinedItem::ImplItem(_, ref item), _)) => Some(item.id), - _ => None - }; + let fn_id = tcx.sess.cstore.maybe_get_item_ast(tcx, def_id).map(|t| t.1); tcx.extern_const_fns.borrow_mut().insert(def_id, fn_id.unwrap_or(ast::DUMMY_NODE_ID)); fn_id } +pub enum ConstFnNode<'tcx> { + Local(FnLikeNode<'tcx>), + Inlined(&'tcx InlinedItem) +} + pub fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Option> + -> Option> { let fn_id = if let Some(node_id) = tcx.map.as_local_node_id(def_id) { node_id } else { if let Some(fn_id) = inline_const_fn_from_external_crate(tcx, def_id) { - fn_id + if let ast_map::NodeInlinedItem(ii) = tcx.map.get(fn_id) { + return Some(ConstFnNode::Inlined(ii)); + } else { + bug!("Got const fn from external crate, but it's not inlined") + } } else { return None; } @@ -224,18 +228,10 @@ pub fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI None => return None }; - match fn_like.kind() { - FnKind::ItemFn(_, _, _, hir::Constness::Const, ..) => { - Some(fn_like) - } - FnKind::Method(_, m, ..) => { - if m.constness == hir::Constness::Const { - Some(fn_like) - } else { - None - } - } - _ => None + if fn_like.constness() == hir::Constness::Const { + Some(ConstFnNode::Local(fn_like)) + } else { + None } } @@ -868,15 +864,22 @@ 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 (decl, result) = if let Some(fn_like) = lookup_const_fn_by_id(tcx, did) { - (fn_like.decl(), fn_like.body()) - } else { - signal!(e, NonConstPath) + 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()), + 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()), + None => signal!(e, NonConstPath), }; - assert_eq!(decl.inputs.len(), args.len()); + let result = tcx.map.expr(body_id); + assert_eq!(arg_defs.len(), args.len()); let mut call_args = DefIdMap(); - for (arg, arg_expr) in decl.inputs.iter().zip(args.iter()) { + for (arg, arg_expr) in arg_defs.into_iter().zip(args.iter()) { let arg_hint = ty_hint.erase_hint(); let arg_val = eval_const_expr_partial( tcx, @@ -885,7 +888,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_args )?; debug!("const call arg: {:?}", arg); - if let PatKind::Binding(_, def_id, _, _) = arg.pat.node { + if let Some(def_id) = arg { assert!(call_args.insert(def_id, arg_val).is_none()); } } @@ -1068,11 +1071,13 @@ fn infer<'a, 'tcx>(i: ConstInt, } } -fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - ti: &'tcx hir::TraitItem, - trait_id: DefId, - rcvr_substs: &'tcx Substs<'tcx>) - -> Option<(&'tcx Expr, Option>)> +fn resolve_trait_associated_const<'a, 'tcx: 'a>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + trait_item_id: DefId, + default_value: Option<(&'tcx Expr, Option>)>, + trait_id: DefId, + rcvr_substs: &'tcx Substs<'tcx> +) -> Option<(&'tcx Expr, Option>)> { let trait_ref = ty::Binder(ty::TraitRef::new(trait_id, rcvr_substs)); debug!("resolve_trait_associated_const: trait_ref={:?}", @@ -1103,21 +1108,16 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // when constructing the inference context above. match selection { traits::VtableImpl(ref impl_data) => { + let name = tcx.associated_item(trait_item_id).name; let ac = tcx.associated_items(impl_data.impl_def_id) - .find(|item| item.kind == ty::AssociatedKind::Const && item.name == ti.name); + .find(|item| item.kind == ty::AssociatedKind::Const && item.name == name); match ac { Some(ic) => lookup_const_by_id(tcx, ic.def_id, None), - None => match ti.node { - hir::ConstTraitItem(ref ty, Some(ref expr)) => { - Some((&*expr, tcx.ast_ty_to_prim_ty(ty))) - }, - _ => None, - }, + None => default_value, } } _ => { - span_bug!(ti.span, - "resolve_trait_associated_const: unexpected vtable type") + bug!("resolve_trait_associated_const: unexpected vtable type") } } }) diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 4759394aff169..f85077766516d 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -696,13 +696,16 @@ impl fold::Folder for ReplaceBodyWithLoop { fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec, tcx: TyCtxt<'a, 'tcx, 'tcx>, - code: blocks::Code, + code: blocks::Code<'tcx>, mode: PpFlowGraphMode, mut out: W) -> io::Result<()> { let cfg = match code { blocks::Code::Expr(expr) => cfg::CFG::new(tcx, expr), - blocks::Code::FnLike(fn_like) => cfg::CFG::new(tcx, fn_like.body()), + blocks::Code::FnLike(fn_like) => { + let body = tcx.map.expr(fn_like.body()); + cfg::CFG::new(tcx, body) + }, }; let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges; let lcfg = LabelledCFG { diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index 250ef061e5109..4595a940f100d 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -34,7 +34,7 @@ use rustc::dep_graph::DepNode; use rustc::hir; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::hir::intravisit as visit; -use rustc::hir::intravisit::Visitor; +use rustc::hir::intravisit::{Visitor, NestedVisitorMap}; use rustc::ty::TyCtxt; use rustc_data_structures::fx::FxHashMap; use rustc::util::common::record_time; @@ -149,19 +149,30 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> { { assert!(def_id.is_local()); debug!("HashItemsVisitor::calculate(def_id={:?})", def_id); + self.calculate_def_hash(DepNode::Hir(def_id), false, &mut walk_op); + self.calculate_def_hash(DepNode::HirBody(def_id), true, &mut walk_op); + } + + fn calculate_def_hash(&mut self, + dep_node: DepNode, + hash_bodies: bool, + walk_op: &mut W) + where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>) + { let mut state = IchHasher::new(); walk_op(&mut StrictVersionHashVisitor::new(&mut state, self.tcx, &mut self.def_path_hashes, &mut self.codemap, - self.hash_spans)); + self.hash_spans, + hash_bodies)); let bytes_hashed = state.bytes_hashed(); let item_hash = state.finish(); - self.hashes.insert(DepNode::Hir(def_id), item_hash); - debug!("calculate_item_hash: def_id={:?} hash={:?}", def_id, item_hash); + debug!("calculate_def_hash: dep_node={:?} hash={:?}", dep_node, item_hash); + self.hashes.insert(dep_node, item_hash); let bytes_hashed = self.tcx.sess.perf_stats.incr_comp_bytes_hashed.get() + - bytes_hashed; + bytes_hashed; self.tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed); } @@ -200,7 +211,8 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> { self.tcx, &mut self.def_path_hashes, &mut self.codemap, - self.hash_spans); + self.hash_spans, + false); visitor.hash_attributes(&krate.attrs); } @@ -212,6 +224,10 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for HashItemsVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::None + } + fn visit_item(&mut self, item: &'tcx hir::Item) { self.calculate_node_id(item.id, |v| v.visit_item(item)); visit::walk_item(self, item); diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index e2b141f2ea62d..681ad2efa0c14 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -52,6 +52,7 @@ pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> { hash_spans: bool, codemap: &'a mut CachingCodemapView<'tcx>, overflow_checks_enabled: bool, + hash_bodies: bool, } impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { @@ -59,7 +60,8 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { tcx: TyCtxt<'hash, 'tcx, 'tcx>, def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>, codemap: &'a mut CachingCodemapView<'tcx>, - hash_spans: bool) + hash_spans: bool, + hash_bodies: bool) -> Self { let check_overflow = tcx.sess.opts.debugging_opts.force_overflow_checks .unwrap_or(tcx.sess.opts.debug_assertions); @@ -71,6 +73,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { hash_spans: hash_spans, codemap: codemap, overflow_checks_enabled: check_overflow, + hash_bodies: hash_bodies, } } @@ -459,15 +462,16 @@ fn saw_ty(node: &Ty_) -> SawTyComponent { #[derive(Hash)] enum SawTraitOrImplItemComponent { SawTraitOrImplItemConst, - SawTraitOrImplItemMethod(Unsafety, Constness, Abi), + // The boolean signifies whether a body is present + SawTraitOrImplItemMethod(Unsafety, Constness, Abi, bool), SawTraitOrImplItemType } fn saw_trait_item(ti: &TraitItem_) -> SawTraitOrImplItemComponent { match *ti { ConstTraitItem(..) => SawTraitOrImplItemConst, - MethodTraitItem(ref sig, _) => - SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi), + MethodTraitItem(ref sig, ref body) => + SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, body.is_some()), TypeTraitItem(..) => SawTraitOrImplItemType } } @@ -476,7 +480,7 @@ fn saw_impl_item(ii: &ImplItemKind) -> SawTraitOrImplItemComponent { match *ii { ImplItemKind::Const(..) => SawTraitOrImplItemConst, ImplItemKind::Method(ref sig, _) => - SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi), + SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, true), ImplItemKind::Type(..) => SawTraitOrImplItemType } } @@ -509,6 +513,14 @@ macro_rules! hash_span { } impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> visit::NestedVisitorMap<'this, 'tcx> { + if self.hash_bodies { + visit::NestedVisitorMap::OnlyBodies(&self.tcx.map) + } else { + visit::NestedVisitorMap::None + } + } + fn visit_variant_data(&mut self, s: &'tcx VariantData, name: Name, @@ -609,7 +621,8 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, n: NodeId) { debug!("visit_mod: st={:?}", self.st); - SawMod.hash(self.st); visit::walk_mod(self, m, n) + SawMod.hash(self.st); + visit::walk_mod(self, m, n) } fn visit_ty(&mut self, t: &'tcx Ty) { diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 85c35bf79ce81..40873011a7b8d 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -114,7 +114,8 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> { match dep_node { DepNode::Krate | - DepNode::Hir(_) => { + DepNode::Hir(_) | + DepNode::HirBody(_) => { // HIR nodes are inputs, so if we are asserting that the HIR node is // dirty, we check the dirty input set. if !self.dirty_inputs.contains(&dep_node) { @@ -143,7 +144,8 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> { match dep_node { DepNode::Krate | - DepNode::Hir(_) => { + DepNode::Hir(_) | + DepNode::HirBody(_) => { // For HIR nodes, check the inputs. if self.dirty_inputs.contains(&dep_node) { let dep_node_str = self.dep_node_str(&dep_node); diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs index 73311ee96c530..562efa4b0d2a8 100644 --- a/src/librustc_incremental/persist/hash.rs +++ b/src/librustc_incremental/persist/hash.rs @@ -45,7 +45,9 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { pub fn is_hashable(dep_node: &DepNode) -> bool { match *dep_node { DepNode::Krate | - DepNode::Hir(_) => true, + DepNode::Hir(_) | + DepNode::HirBody(_) => + true, DepNode::MetaData(def_id) => !def_id.is_local(), _ => false, } @@ -58,7 +60,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { } // HIR nodes (which always come from our crate) are an input: - DepNode::Hir(def_id) => { + DepNode::Hir(def_id) | DepNode::HirBody(def_id) => { assert!(def_id.is_local(), "cannot hash HIR for non-local def-id {:?} => {:?}", def_id, diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 289eebb216208..05e21aa19b1b8 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -145,8 +145,8 @@ pub fn encode_dep_graph(preds: &Predecessors, for (&target, sources) in &preds.inputs { match *target { DepNode::MetaData(ref def_id) => { - // Metadata *targets* are always local metadata nodes. We handle - // those in `encode_metadata_hashes`, which comes later. + // Metadata *targets* are always local metadata nodes. We have + // already handled those in `encode_metadata_hashes`. assert!(def_id.is_local()); continue; } diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 806d20c72dcd9..6598b7dcc527f 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -10,7 +10,7 @@ use rustc::hir::map as ast_map; -use rustc::hir::intravisit::{Visitor, IdRangeComputingVisitor, IdRange}; +use rustc::hir::intravisit::{Visitor, IdRangeComputingVisitor, IdRange, NestedVisitorMap}; use cstore::CrateMetadata; use encoder::EncodeContext; @@ -43,13 +43,9 @@ enum TableEntry<'tcx> { } impl<'a, 'tcx> EncodeContext<'a, 'tcx> { - pub fn encode_inlined_item(&mut self, ii: InlinedItemRef) -> Lazy> { - let mut id_visitor = IdRangeComputingVisitor::new(); - match ii { - InlinedItemRef::Item(_, i) => id_visitor.visit_item(i), - InlinedItemRef::TraitItem(_, ti) => id_visitor.visit_trait_item(ti), - InlinedItemRef::ImplItem(_, ii) => id_visitor.visit_impl_item(ii), - } + pub fn encode_inlined_item(&mut self, ii: InlinedItemRef<'tcx>) -> Lazy> { + let mut id_visitor = IdRangeComputingVisitor::new(&self.tcx.map); + ii.visit(&mut id_visitor); let ii_pos = self.position(); ii.encode(self).unwrap(); @@ -60,11 +56,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ecx: self, count: 0, }; - match ii { - InlinedItemRef::Item(_, i) => visitor.visit_item(i), - InlinedItemRef::TraitItem(_, ti) => visitor.visit_trait_item(ti), - InlinedItemRef::ImplItem(_, ii) => visitor.visit_impl_item(ii), - } + ii.visit(&mut visitor); visitor.count }; @@ -81,7 +73,11 @@ struct SideTableEncodingIdVisitor<'a, 'b: 'a, 'tcx: 'b> { count: usize, } -impl<'a, 'b, 'tcx, 'v> Visitor<'v> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> { +impl<'a, 'b, 'tcx> Visitor<'tcx> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.ecx.tcx.map) + } + fn visit_id(&mut self, id: ast::NodeId) { debug!("Encoding side tables for id {}", id); @@ -122,17 +118,13 @@ pub fn decode_inlined_item<'a, 'tcx>(cdata: &CrateMetadata, }]; let ii = ast.item.decode((cdata, tcx, id_ranges)); + let item_node_id = tcx.sess.next_node_id(); let ii = ast_map::map_decoded_item(&tcx.map, parent_def_path, parent_did, ii, - tcx.sess.next_node_id()); + item_node_id); - let item_node_id = match ii { - &InlinedItem::Item(_, ref i) => i.id, - &InlinedItem::TraitItem(_, ref ti) => ti.id, - &InlinedItem::ImplItem(_, ref ii) => ii.id, - }; let inlined_did = tcx.map.local_def_id(item_node_id); let ty = tcx.item_type(orig_did); let generics = tcx.item_generics(orig_did); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 4b90d9259724b..573b2f6d2a60c 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -443,12 +443,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { let find_inlined_item_root = |inlined_item_id| { let mut node = inlined_item_id; - let mut path = Vec::with_capacity(10); // If we can't find the inline root after a thousand hops, we can // be pretty sure there's something wrong with the HIR map. for _ in 0 .. 1000 { - path.push(node); let parent_node = tcx.map.get_parent_node(node); if parent_node == node { return node; @@ -464,27 +462,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { .borrow_mut() .insert(def_id, None); } - Some(&InlinedItem::Item(d, ref item)) => { - assert_eq!(d, def_id); - let inlined_root_node_id = find_inlined_item_root(item.id); - cache_inlined_item(def_id, item.id, inlined_root_node_id); - } - Some(&InlinedItem::TraitItem(_, ref trait_item)) => { - let inlined_root_node_id = find_inlined_item_root(trait_item.id); - cache_inlined_item(def_id, trait_item.id, inlined_root_node_id); - - // Associated consts already have to be evaluated in `typeck`, so - // the logic to do that already exists in `middle`. In order to - // reuse that code, it needs to be able to look up the traits for - // inlined items. - let ty_trait_item = tcx.associated_item(def_id).clone(); - let trait_item_def_id = tcx.map.local_def_id(trait_item.id); - tcx.associated_items.borrow_mut() - .insert(trait_item_def_id, ty_trait_item); - } - Some(&InlinedItem::ImplItem(_, ref impl_item)) => { - let inlined_root_node_id = find_inlined_item_root(impl_item.id); - cache_inlined_item(def_id, impl_item.id, inlined_root_node_id); + Some(&InlinedItem { ref body, .. }) => { + let inlined_root_node_id = find_inlined_item_root(body.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 a243962b4eef8..4839c409335ea 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -39,7 +39,7 @@ use syntax_pos; use rustc::hir::{self, PatKind}; use rustc::hir::itemlikevisit::ItemLikeVisitor; -use rustc::hir::intravisit::Visitor; +use rustc::hir::intravisit::{Visitor, NestedVisitorMap}; use rustc::hir::intravisit; use super::index_builder::{FromId, IndexBuilder, Untracked}; @@ -516,9 +516,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { generics: Some(self.encode_generics(def_id)), predicates: Some(self.encode_predicates(def_id)), - ast: if trait_item.kind == ty::AssociatedKind::Const { + ast: if let hir::ConstTraitItem(_, Some(_)) = ast_item.node { + // We only save the HIR for associated consts with bodies + // (InlinedItemRef::from_trait_item panics otherwise) let trait_def_id = trait_item.container.id(); - Some(self.encode_inlined_item(InlinedItemRef::TraitItem(trait_def_id, ast_item))) + Some(self.encode_inlined_item( + InlinedItemRef::from_trait_item(trait_def_id, ast_item, tcx) + )) } else { None }, @@ -527,6 +531,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> { + let tcx = self.tcx; + let node_id = self.tcx.map.as_local_node_id(def_id).unwrap(); let ast_item = self.tcx.map.expect_impl_item(node_id); let impl_item = self.tcx.associated_item(def_id); @@ -587,7 +593,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { predicates: Some(self.encode_predicates(def_id)), ast: if ast { - Some(self.encode_inlined_item(InlinedItemRef::ImplItem(impl_def_id, ast_item))) + Some(self.encode_inlined_item( + InlinedItemRef::from_impl_item(impl_def_id, ast_item, tcx) + )) } else { None }, @@ -630,7 +638,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr)) } - fn encode_info_for_item(&mut self, (def_id, item): (DefId, &hir::Item)) -> Entry<'tcx> { + fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) -> Entry<'tcx> { let tcx = self.tcx; debug!("encoding info for item at {}", @@ -817,7 +825,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ast: match item.node { hir::ItemConst(..) | hir::ItemFn(_, _, hir::Constness::Const, ..) => { - Some(self.encode_inlined_item(InlinedItemRef::Item(def_id, item))) + Some(self.encode_inlined_item( + InlinedItemRef::from_item(def_id, item, tcx) + )) } _ => None, }, @@ -973,6 +983,9 @@ struct EncodeVisitor<'a, 'b: 'a, 'tcx: 'b> { } impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.index.tcx.map) + } fn visit_expr(&mut self, ex: &'tcx hir::Expr) { intravisit::walk_expr(self, ex); self.index.encode_info_for_expr(ex); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index a148ae08c53a4..94bf8936fe61b 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -736,7 +736,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(.., ref body, _) => body.id, + hir::ExprClosure(.., body_id, _) => body_id.node_id(), _ => { span_bug!(expr.span, "closure expr is not a closure expr"); } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index cfeac606f03d0..32639cc3f8696 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -23,7 +23,6 @@ use rustc_const_eval as const_eval; use rustc_data_structures::indexed_vec::Idx; use rustc::dep_graph::DepNode; use rustc::hir::def_id::DefId; -use rustc::hir::intravisit::FnKind; use rustc::hir::map::blocks::FnLikeNode; use rustc::infer::InferCtxt; use rustc::ty::subst::Subst; @@ -51,11 +50,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { MirSource::Static(..) => hir::Constness::Const, MirSource::Fn(id) => { let fn_like = FnLikeNode::from_node(infcx.tcx.map.get(id)); - match fn_like.map(|f| f.kind()) { - Some(FnKind::ItemFn(_, _, _, c, ..)) => c, - Some(FnKind::Method(_, m, ..)) => m.constness, - _ => hir::Constness::NotConst - } + fn_like.map_or(hir::Constness::NotConst, |f| f.constness()) } MirSource::Promoted(..) => bug!() }; diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index 992c0e9b5fc85..88d02d7d004c9 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -30,7 +30,7 @@ use rustc::traits::Reveal; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::Substs; use rustc::hir; -use rustc::hir::intravisit::{self, FnKind, Visitor}; +use rustc::hir::intravisit::{self, FnKind, Visitor, NestedVisitorMap}; use syntax::abi::Abi; use syntax::ast; use syntax_pos::Span; @@ -144,6 +144,10 @@ impl<'a, 'gcx> BuildMir<'a, 'gcx> { } impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + // Const and static items. fn visit_item(&mut self, item: &'tcx hir::Item) { match item.node { @@ -210,7 +214,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { fn visit_fn(&mut self, fk: FnKind<'tcx>, decl: &'tcx hir::FnDecl, - body: &'tcx hir::Expr, + body_id: hir::ExprId, span: Span, id: ast::NodeId) { // fetch the fully liberated fn signature (that is, all bound @@ -223,7 +227,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), 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) @@ -237,12 +241,14 @@ 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) }); - intravisit::walk_fn(self, fk, decl, body, span, id); + intravisit::walk_fn(self, fk, decl, body_id, span, id); } } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 4ff2beb3fdb77..57929879f9402 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -19,7 +19,6 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc::hir; use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; -use rustc::hir::intravisit::FnKind; use rustc::hir::map::blocks::FnLikeNode; use rustc::traits::{self, Reveal}; use rustc::ty::{self, TyCtxt, Ty}; @@ -116,15 +115,10 @@ impl fmt::Display for Mode { pub fn is_const_fn(tcx: TyCtxt, def_id: DefId) -> bool { if let Some(node_id) = tcx.map.as_local_node_id(def_id) { - let fn_like = FnLikeNode::from_node(tcx.map.get(node_id)); - match fn_like.map(|f| f.kind()) { - Some(FnKind::ItemFn(_, _, _, c, ..)) => { - c == hir::Constness::Const - } - Some(FnKind::Method(_, m, ..)) => { - m.constness == hir::Constness::Const - } - _ => false + if let Some(fn_like) = FnLikeNode::from_node(tcx.map.get(node_id)) { + fn_like.constness() == hir::Constness::Const + } else { + false } } else { tcx.sess.cstore.is_const_fn(def_id) diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index d9b1f247c7270..86f56d0035841 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -27,7 +27,7 @@ use rustc::dep_graph::DepNode; use rustc::ty::cast::CastKind; use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, compare_lit_exprs}; -use rustc_const_eval::{eval_const_expr_partial, lookup_const_by_id}; +use rustc_const_eval::{ConstFnNode, eval_const_expr_partial, lookup_const_by_id}; use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal, MiscCatchAll, Math}; use rustc_const_eval::ErrKind::{ErroneousReferencedConstant, MiscBinaryOp, NonConstPath}; use rustc_const_eval::ErrKind::UnresolvedPath; @@ -48,7 +48,7 @@ use rustc::lint::builtin::CONST_ERR; use rustc::hir::{self, PatKind}; use syntax::ast; use syntax_pos::Span; -use rustc::hir::intravisit::{self, FnKind, Visitor}; +use rustc::hir::intravisit::{self, FnKind, Visitor, NestedVisitorMap}; use std::collections::hash_map::Entry; use std::cmp::Ordering; @@ -100,7 +100,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { .enter(|infcx| f(&mut euv::ExprUseVisitor::new(self, &infcx))) } - fn global_expr(&mut self, mode: Mode, expr: &hir::Expr) -> ConstQualif { + 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) { Entry::Occupied(entry) => return *entry.get(), @@ -132,9 +132,9 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { } fn fn_like(&mut self, - fk: FnKind, - fd: &hir::FnDecl, - b: &hir::Expr, + fk: FnKind<'gcx>, + fd: &'gcx hir::FnDecl, + b: hir::ExprId, s: Span, fn_id: ast::NodeId) -> ConstQualif { @@ -160,7 +160,8 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { }; let qualif = self.with_mode(mode, |this| { - this.with_euv(Some(fn_id), |euv| euv.walk_fn(fd, b)); + let body = this.tcx.map.expr(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 }); @@ -179,21 +180,39 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { /// Returns true if the call is to a const fn or method. fn handle_const_fn_call(&mut self, _expr: &hir::Expr, def_id: DefId, ret_ty: Ty<'gcx>) -> bool { - if let Some(fn_like) = lookup_const_fn_by_id(self.tcx, def_id) { - let qualif = self.fn_like(fn_like.kind(), - fn_like.decl(), - fn_like.body(), - fn_like.span(), - fn_like.id()); - self.add_qualif(qualif); + match lookup_const_fn_by_id(self.tcx, def_id) { + Some(ConstFnNode::Local(fn_like)) => { + let qualif = self.fn_like(fn_like.kind(), + fn_like.decl(), + fn_like.body(), + fn_like.span(), + fn_like.id()); - if ret_ty.type_contents(self.tcx).interior_unsafe() { - self.add_qualif(ConstQualif::MUTABLE_MEM); - } + self.add_qualif(qualif); + + if ret_ty.type_contents(self.tcx).interior_unsafe() { + self.add_qualif(ConstQualif::MUTABLE_MEM); + } + + true + }, + Some(ConstFnNode::Inlined(ii)) => { + let node_id = ii.body.id; + + let qualif = match self.tcx.const_qualif_map.borrow_mut().entry(node_id) { + Entry::Occupied(entry) => *entry.get(), + _ => bug!("const qualif entry missing for inlined item") + }; - true - } else { - false + self.add_qualif(qualif); + + if ret_ty.type_contents(self.tcx).interior_unsafe() { + self.add_qualif(ConstQualif::MUTABLE_MEM); + } + + true + }, + None => false } } @@ -213,8 +232,12 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { } } -impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { - fn visit_item(&mut self, i: &hir::Item) { +impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + + fn visit_item(&mut self, i: &'tcx hir::Item) { debug!("visit_item(item={})", self.tcx.map.node_to_string(i.id)); assert_eq!(self.mode, Mode::Var); match i.node { @@ -240,7 +263,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { } } - fn visit_trait_item(&mut self, t: &'v hir::TraitItem) { + fn visit_trait_item(&mut self, t: &'tcx hir::TraitItem) { match t.node { hir::ConstTraitItem(_, ref default) => { if let Some(ref expr) = *default { @@ -253,7 +276,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { } } - fn visit_impl_item(&mut self, i: &'v hir::ImplItem) { + fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) { match i.node { hir::ImplItemKind::Const(_, ref expr) => { self.global_expr(Mode::Const, &expr); @@ -263,15 +286,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { } fn visit_fn(&mut self, - fk: FnKind<'v>, - fd: &'v hir::FnDecl, - b: &'v hir::Expr, + fk: FnKind<'tcx>, + fd: &'tcx hir::FnDecl, + b: hir::ExprId, s: Span, fn_id: ast::NodeId) { self.fn_like(fk, fd, b, s, fn_id); } - fn visit_pat(&mut self, p: &hir::Pat) { + fn visit_pat(&mut self, p: &'tcx hir::Pat) { match p.node { PatKind::Lit(ref lit) => { self.global_expr(Mode::Const, &lit); @@ -296,7 +319,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { } } - fn visit_block(&mut self, block: &hir::Block) { + fn visit_block(&mut self, block: &'tcx hir::Block) { // Check all statements in the block for stmt in &block.stmts { match stmt.node { @@ -315,7 +338,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { intravisit::walk_block(self, block); } - fn visit_expr(&mut self, ex: &hir::Expr) { + fn visit_expr(&mut self, ex: &'tcx hir::Expr) { let mut outer = self.qualif; self.qualif = ConstQualif::empty(); diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index ba236ea93a4bc..b785801398895 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -106,7 +106,7 @@ impl<'k> StatCollector<'k> { } impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { - fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'v>> { + fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'v> { panic!("visit_nested_xxx must be manually implemented in this visitor") } @@ -172,7 +172,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: &'v hir::Expr, + b: hir::ExprId, 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 a622a3faf7098..10f464a9901d0 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -13,7 +13,7 @@ use rustc::session::Session; use rustc::dep_graph::DepNode; use rustc::hir::map::Map; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; use syntax::ast; use syntax_pos::Span; @@ -59,16 +59,20 @@ pub fn check_crate(sess: &Session, map: &Map) { }.as_deep_visitor()); } -impl<'a, 'ast, 'v> Visitor<'v> for CheckLoopVisitor<'a, 'ast> { - fn visit_item(&mut self, i: &hir::Item) { +impl<'a, 'ast> Visitor<'ast> for CheckLoopVisitor<'a, 'ast> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { + NestedVisitorMap::OnlyBodies(&self.hir_map) + } + + fn visit_item(&mut self, i: &'ast hir::Item) { self.with_context(Normal, |v| intravisit::walk_item(v, i)); } - fn visit_impl_item(&mut self, i: &hir::ImplItem) { + fn visit_impl_item(&mut self, i: &'ast hir::ImplItem) { self.with_context(Normal, |v| intravisit::walk_impl_item(v, i)); } - fn visit_expr(&mut self, e: &hir::Expr) { + fn visit_expr(&mut self, e: &'ast hir::Expr) { match e.node { hir::ExprWhile(ref e, ref b, _) => { self.with_context(Loop(LoopKind::WhileLoop), |v| { @@ -79,8 +83,8 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckLoopVisitor<'a, 'ast> { hir::ExprLoop(ref b, _, source) => { self.with_context(Loop(LoopKind::Loop(source)), |v| v.visit_block(&b)); } - hir::ExprClosure(.., ref b, _) => { - self.with_context(Closure, |v| v.visit_expr(&b)); + hir::ExprClosure(.., b, _) => { + self.with_context(Closure, |v| v.visit_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 7386be2528c9b..ddb5af1e80c34 100644 --- a/src/librustc_passes/rvalues.rs +++ b/src/librustc_passes/rvalues.rs @@ -18,7 +18,7 @@ use rustc::ty::{self, TyCtxt, ParameterEnvironment}; use rustc::traits::Reveal; use rustc::hir; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use syntax::ast; use syntax_pos::Span; @@ -31,11 +31,15 @@ struct RvalueContext<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } -impl<'a, 'tcx, 'v> Visitor<'v> for RvalueContext<'a, 'tcx> { +impl<'a, 'tcx> Visitor<'tcx> for RvalueContext<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + fn visit_fn(&mut self, - fk: intravisit::FnKind<'v>, - fd: &'v hir::FnDecl, - b: &'v hir::Expr, + fk: intravisit::FnKind<'tcx>, + fd: &'tcx hir::FnDecl, + b: hir::ExprId, s: Span, fn_id: ast::NodeId) { // FIXME (@jroesch) change this to be an inference context @@ -46,8 +50,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for RvalueContext<'a, 'tcx> { tcx: infcx.tcx, param_env: ¶m_env }; + let body = infcx.tcx.map.expr(b); let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); - euv.walk_fn(fd, b); + euv.walk_fn(fd, body); }); intravisit::walk_fn(self, fk, fd, b, s, fn_id) } diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index b5daf0284e1d6..ffb5045fe3b07 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -20,7 +20,7 @@ use rustc::util::nodemap::NodeMap; use syntax::ast; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax_pos::Span; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; use std::cell::RefCell; @@ -36,6 +36,10 @@ struct CheckCrateVisitor<'a, 'ast: 'a> { } impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { + NestedVisitorMap::None + } + fn visit_item(&mut self, it: &'ast hir::Item) { match it.node { hir::ItemStatic(..) | @@ -200,6 +204,10 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> { } impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { + NestedVisitorMap::OnlyBodies(&self.ast_map) + } + fn visit_item(&mut self, it: &'ast hir::Item) { self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it), it.span); } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index ee18968ff35e3..8b8172bf5b5c2 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -30,7 +30,7 @@ use rustc::dep_graph::DepNode; use rustc::hir::{self, PatKind}; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::DefId; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::itemlikevisit::DeepVisitor; use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::lint; @@ -120,8 +120,8 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { /// We want to visit items in the context of their containing /// module and so forth, so supply a crate for doing a deep walk. - fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> { - Some(&self.tcx.map) + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::All(&self.tcx.map) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -432,8 +432,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for PrivacyVisitor<'a, 'tcx> { /// We want to visit items in the context of their containing /// module and so forth, so supply a crate for doing a deep walk. - fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> { - Some(&self.tcx.map) + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::All(&self.tcx.map) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -615,6 +615,10 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { + NestedVisitorMap::None + } + fn visit_ty(&mut self, ty: &hir::Ty) { if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = ty.node { if self.inner.path_is_private_type(path) { @@ -640,8 +644,8 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { /// We want to visit items in the context of their containing /// module and so forth, so supply a crate for doing a deep walk. - fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> { - Some(&self.tcx.map) + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::All(&self.tcx.map) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -1059,8 +1063,12 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { } } -impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { - fn visit_item(&mut self, item: &hir::Item) { +impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + + fn visit_item(&mut self, item: &'tcx hir::Item) { let tcx = self.tcx; let min = |vis1: ty::Visibility, vis2| { if vis1.is_at_least(vis2, &tcx.map) { vis2 } else { vis1 } @@ -1163,11 +1171,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc } } - fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem) { + fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) { // handled in `visit_item` above } - fn visit_ty(&mut self, ty: &hir::Ty) { + fn visit_ty(&mut self, ty: &'tcx hir::Ty) { if let hir::TyImplTrait(..) = ty.node { // Check the traits being exposed, as they're separate, // e.g. `impl Iterator` has two predicates, @@ -1181,9 +1189,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc } // Don't recurse into expressions in array sizes or const initializers - fn visit_expr(&mut self, _: &hir::Expr) {} + fn visit_expr(&mut self, _: &'tcx hir::Expr) {} // Don't recurse into patterns in function arguments - fn visit_pat(&mut self, _: &hir::Pat) {} + fn visit_pat(&mut self, _: &'tcx hir::Pat) {} } pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_trans/symbol_names_test.rs b/src/librustc_trans/symbol_names_test.rs index aa23a18172276..9ed5a5d148cd6 100644 --- a/src/librustc_trans/symbol_names_test.rs +++ b/src/librustc_trans/symbol_names_test.rs @@ -15,7 +15,7 @@ //! paths etc in all kinds of annoying scenarios. use rustc::hir; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use syntax::ast; use common::SharedCrateContext; @@ -67,6 +67,10 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> { } impl<'a, 'tcx> Visitor<'tcx> for SymbolNamesTest<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::None + } + fn visit_item(&mut self, item: &'tcx hir::Item) { self.process_attrs(item.id); intravisit::walk_item(self, item); diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 75287d4064ae1..0854ca3d1bb26 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -23,7 +23,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr: &hir::Expr, _capture: hir::CaptureClause, decl: &'gcx hir::FnDecl, - body: &'gcx hir::Expr, + body_id: hir::ExprId, expected: Expectation<'tcx>) -> Ty<'tcx> { debug!("check_expr_closure(expr={:?},expected={:?})", @@ -37,6 +37,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); self.check_closure(expr, expected_kind, decl, body, expected_sig) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2babb81bc407a..0c4e5e4fa0dfc 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -119,7 +119,7 @@ use syntax::symbol::{Symbol, InternedString, keywords}; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::{self, BytePos, Span}; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::{self, PatKind}; use rustc::hir::print as pprust; @@ -538,6 +538,10 @@ struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.ccx.tcx.map) + } + fn visit_item(&mut self, i: &'tcx hir::Item) { check_item_type(self.ccx, i); intravisit::walk_item(self, i); @@ -630,9 +634,11 @@ pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult { fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, decl: &'tcx hir::FnDecl, - body: &'tcx hir::Expr, + body_id: hir::ExprId, fn_id: ast::NodeId, span: Span) { + let body = ccx.tcx.map.expr(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, @@ -643,13 +649,13 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, 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); + 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, &fn_sig); + inh.normalize_associated_types_in(body.span, body_id.node_id(), &fn_sig); let fcx = check_fn(&inh, fn_ty.unsafety, fn_id, &fn_sig, decl, fn_id, body); @@ -659,7 +665,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); + fcx.regionck_fn(fn_id, decl, body_id); fcx.resolve_type_vars_in_fn(decl, body, fn_id); }); } @@ -694,6 +700,10 @@ impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, 'tcx> { } impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> { + NestedVisitorMap::None + } + // Add explicitly-declared locals. fn visit_local(&mut self, local: &'gcx hir::Local) { let o_ty = match local.ty { @@ -750,7 +760,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, - _: &'gcx hir::Expr, _: Span, _: ast::NodeId) { } + _: hir::ExprId, _: Span, _: ast::NodeId) { } } /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function @@ -911,8 +921,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id))); let _indenter = indenter(); match it.node { - hir::ItemFn(ref decl, .., ref body) => { - check_bare_fn(ccx, &decl, &body, it.id, it.span); + hir::ItemFn(ref decl, .., body_id) => { + check_bare_fn(ccx, &decl, body_id, it.id, it.span); } hir::ItemImpl(.., ref impl_item_refs) => { debug!("ItemImpl {} with id {}", it.name, it.id); @@ -923,8 +933,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { hir::ImplItemKind::Const(_, ref expr) => { check_const(ccx, &expr, impl_item.id) } - hir::ImplItemKind::Method(ref sig, ref body) => { - check_bare_fn(ccx, &sig.decl, body, impl_item.id, impl_item.span); + hir::ImplItemKind::Method(ref sig, body_id) => { + check_bare_fn(ccx, &sig.decl, body_id, impl_item.id, impl_item.span); } hir::ImplItemKind::Type(_) => { // Nothing to do here. @@ -938,8 +948,8 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { hir::ConstTraitItem(_, Some(ref expr)) => { check_const(ccx, &expr, trait_item.id) } - hir::MethodTraitItem(ref sig, Some(ref body)) => { - check_bare_fn(ccx, &sig.decl, body, trait_item.id, trait_item.span); + hir::MethodTraitItem(ref sig, Some(body_id)) => { + check_bare_fn(ccx, &sig.decl, body_id, trait_item.id, trait_item.span); } hir::MethodTraitItem(_, None) | hir::ConstTraitItem(_, None) | @@ -1102,14 +1112,14 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, err.emit() } } - hir::ImplItemKind::Method(_, ref body) => { + hir::ImplItemKind::Method(_, body_id) => { let trait_span = tcx.map.span_if_local(ty_trait_item.def_id); if ty_trait_item.kind == ty::AssociatedKind::Method { let err_count = tcx.sess.err_count(); compare_impl_method(ccx, &ty_impl_item, impl_item.span, - body.id, + body_id.node_id(), &ty_trait_item, impl_trait_ref, trait_span, @@ -1119,7 +1129,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, + body_id.node_id(), &ty_trait_item, impl_trait_ref, trait_span, @@ -3791,8 +3801,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::ExprMatch(ref discrim, ref arms, match_src) => { self.check_match(expr, &discrim, arms, expected, match_src) } - hir::ExprClosure(capture, ref decl, ref body, _) => { - self.check_expr_closure(expr, capture, &decl, &body, expected) + hir::ExprClosure(capture, ref decl, body_id, _) => { + self.check_expr_closure(expr, capture, &decl, body_id, expected) } hir::ExprBlock(ref b) => { self.check_block_with_expected(&b, expected) diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index ca33682480c4c..3cc99b6e4e5aa 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -99,7 +99,7 @@ use std::mem; use std::ops::Deref; use syntax::ast; use syntax_pos::Span; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::{self, PatKind}; use self::SubjectNode::Subject; @@ -113,7 +113,7 @@ macro_rules! ignore_err { // PUBLIC ENTRY POINTS impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { - pub fn regionck_expr(&self, e: &hir::Expr) { + pub fn regionck_expr(&self, e: &'gcx hir::Expr) { let mut rcx = RegionCtxt::new(self, RepeatingScope(e.id), e.id, Subject(e.id)); if self.err_count_since_creation() == 0 { // regionck assumes typeck succeeded @@ -141,13 +141,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn regionck_fn(&self, fn_id: ast::NodeId, decl: &hir::FnDecl, - body: &hir::Expr) { + body_id: hir::ExprId) { debug!("regionck_fn(id={})", fn_id); - let mut rcx = RegionCtxt::new(self, RepeatingScope(body.id), body.id, Subject(fn_id)); + let node_id = body_id.node_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, self.tcx.map.span(fn_id)); + rcx.visit_fn_body(fn_id, decl, body_id, self.tcx.map.span(fn_id)); } rcx.free_region_map.relate_free_regions_from_predicates( @@ -267,14 +268,14 @@ 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: &hir::Expr, + body_id: hir::ExprId, span: Span) { // When we enter a function, we can derive debug!("visit_fn_body(id={})", id); let call_site = self.tcx.region_maps.lookup_code_extent( - region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body.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 = { @@ -300,19 +301,20 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { .chain(Some(fn_sig.output)) .collect(); - let old_body_id = self.set_body_id(body.id); - self.relate_free_regions(&fn_sig_tys[..], body.id, span); - self.link_fn_args(self.tcx.region_maps.node_extent(body.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); + 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); let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope)); self.type_of_node_must_outlive(infer::CallReturn(span), - body.id, + body_id.node_id(), call_site_region); self.region_bound_pairs.truncate(old_region_bounds_pairs_len); @@ -469,7 +471,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // (..) FIXME(#3238) should use visit_pat, not visit_arm/visit_local, // However, right now we run into an issue whereby some free // regions are not properly related if they appear within the @@ -478,14 +480,18 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> { // hierarchy, and in particular the relationships between free // regions, until regionck, as described in #3238. - fn visit_fn(&mut self, _fk: intravisit::FnKind<'v>, fd: &'v hir::FnDecl, - b: &'v hir::Expr, span: Span, id: ast::NodeId) { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.map) + } + + 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) } //visit_pat: visit_pat, // (..) see above - fn visit_arm(&mut self, arm: &hir::Arm) { + fn visit_arm(&mut self, arm: &'gcx hir::Arm) { // see above for p in &arm.pats { self.constrain_bindings_in_pat(p); @@ -493,14 +499,14 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> { intravisit::walk_arm(self, arm); } - fn visit_local(&mut self, l: &hir::Local) { + fn visit_local(&mut self, l: &'gcx hir::Local) { // see above self.constrain_bindings_in_pat(&l.pat); self.link_local(l); intravisit::walk_local(self, l); } - fn visit_expr(&mut self, expr: &hir::Expr) { + fn visit_expr(&mut self, expr: &'gcx hir::Expr) { debug!("regionck::visit_expr(e={:?}, repeating_scope={})", expr, self.repeating_scope); @@ -737,8 +743,8 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for RegionCtxt<'a, 'gcx, 'tcx> { intravisit::walk_expr(self, expr); } - hir::ExprClosure(.., ref body, _) => { - self.check_expr_fn_block(expr, &body); + hir::ExprClosure(.., body_id, _) => { + self.check_expr_fn_block(expr, body_id); } hir::ExprLoop(ref body, _, _) => { @@ -823,9 +829,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } fn check_expr_fn_block(&mut self, - expr: &hir::Expr, - body: &hir::Expr) { - let repeating_scope = self.set_repeating_scope(body.id); + expr: &'gcx hir::Expr, + body_id: hir::ExprId) { + 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 1ea47107c3b18..63d20416bded5 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -50,14 +50,14 @@ use rustc::infer::UpvarRegion; use syntax::ast; use syntax_pos::Span; use rustc::hir; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::util::nodemap::NodeMap; /////////////////////////////////////////////////////////////////////////// // PUBLIC ENTRY POINTS impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { - pub fn closure_analyze(&self, body: &hir::Expr) { + pub fn closure_analyze(&self, body: &'gcx hir::Expr) { let mut seed = SeedBorrowKind::new(self); seed.visit_expr(body); @@ -77,11 +77,15 @@ struct SeedBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { temp_closure_kinds: NodeMap, } -impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for SeedBorrowKind<'a, 'gcx, 'tcx> { - fn visit_expr(&mut self, expr: &hir::Expr) { +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) + } + + fn visit_expr(&mut self, expr: &'gcx hir::Expr) { match expr.node { - hir::ExprClosure(cc, _, ref body, _) => { - self.check_closure(expr, cc, &body); + hir::ExprClosure(cc, _, body_id, _) => { + self.check_closure(expr, cc, body_id); } _ => { } @@ -99,7 +103,7 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> { fn check_closure(&mut self, expr: &hir::Expr, capture_clause: hir::CaptureClause, - _body: &hir::Expr) + _body_id: hir::ExprId) { 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) { @@ -153,14 +157,15 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { id: ast::NodeId, span: Span, decl: &hir::FnDecl, - body: &hir::Expr) { + body_id: hir::ExprId) { /*! * 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, @@ -484,11 +489,15 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for 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) + } + fn visit_fn(&mut self, - fn_kind: intravisit::FnKind<'v>, - decl: &'v hir::FnDecl, - body: &'v hir::Expr, + fn_kind: intravisit::FnKind<'gcx>, + decl: &'gcx hir::FnDecl, + body: hir::ExprId, span: Span, id: ast::NodeId) { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 1ad81660f836a..b6d0ff03a07ab 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -23,7 +23,7 @@ use syntax::ast; use syntax_pos::Span; use errors::DiagnosticBuilder; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> { @@ -127,8 +127,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { } } } - hir::ItemFn(.., ref body) => { - self.check_item_fn(item, body); + hir::ItemFn(.., body_id) => { + self.check_item_fn(item, body_id); } hir::ItemStatic(..) => { self.check_item_type(item); @@ -347,7 +347,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { fn check_item_fn(&mut self, item: &hir::Item, - body: &hir::Expr) + body_id: hir::ExprId) { self.for_item(item).with_fcx(|fcx, this| { let free_substs = &fcx.parameter_environment.free_substs; @@ -364,7 +364,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); + 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 @@ -609,6 +609,10 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, def_id: DefId) { } impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { + NestedVisitorMap::None + } + fn visit_item(&mut self, i: &hir::Item) { debug!("visit_item: {:?}", i); self.check_item_well_formed(i); diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 45b3dae3e9f83..84b0303e5cfbb 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -27,14 +27,14 @@ use syntax::ast; use syntax_pos::{DUMMY_SP, Span}; use rustc::hir::print::pat_to_string; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; 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: &hir::Expr, item_id: ast::NodeId) { + pub fn resolve_type_vars_in_expr(&self, e: &'gcx hir::Expr, item_id: ast::NodeId) { assert_eq!(self.writeback_errors.get(), false); let mut wbcx = WritebackCx::new(self); wbcx.visit_expr(e); @@ -47,8 +47,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } pub fn resolve_type_vars_in_fn(&self, - decl: &hir::FnDecl, - body: &hir::Expr, + decl: &'gcx hir::FnDecl, + body: &'gcx hir::Expr, item_id: ast::NodeId) { assert_eq!(self.writeback_errors.get(), false); let mut wbcx = WritebackCx::new(self); @@ -186,8 +186,12 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { // below. In general, a function is made into a `visitor` if it must // traffic in node-ids or update tables in the type context etc. -impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> { - fn visit_stmt(&mut self, s: &hir::Stmt) { +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) + } + + fn visit_stmt(&mut self, s: &'gcx hir::Stmt) { if self.fcx.writeback_errors.get() { return; } @@ -196,7 +200,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> { intravisit::walk_stmt(self, s); } - fn visit_expr(&mut self, e: &hir::Expr) { + fn visit_expr(&mut self, e: &'gcx hir::Expr) { if self.fcx.writeback_errors.get() { return; } @@ -216,7 +220,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> { intravisit::walk_expr(self, e); } - fn visit_block(&mut self, b: &hir::Block) { + fn visit_block(&mut self, b: &'gcx hir::Block) { if self.fcx.writeback_errors.get() { return; } @@ -225,7 +229,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> { intravisit::walk_block(self, b); } - fn visit_pat(&mut self, p: &hir::Pat) { + fn visit_pat(&mut self, p: &'gcx hir::Pat) { if self.fcx.writeback_errors.get() { return; } @@ -240,7 +244,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> { intravisit::walk_pat(self, p); } - fn visit_local(&mut self, l: &hir::Local) { + fn visit_local(&mut self, l: &'gcx hir::Local) { if self.fcx.writeback_errors.get() { return; } @@ -251,7 +255,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> { intravisit::walk_local(self, l); } - fn visit_ty(&mut self, t: &hir::Ty) { + fn visit_ty(&mut self, t: &'gcx hir::Ty) { match t.node { hir::TyArray(ref ty, ref count_expr) => { self.visit_ty(&ty); diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index a507077bef77e..abbf5601484bc 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -385,7 +385,6 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { self.check_item(item); } - fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) { } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 0dcc0bcc316ce..011c82625186f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -83,7 +83,7 @@ use syntax::symbol::{Symbol, keywords}; use syntax_pos::Span; use rustc::hir::{self, map as hir_map, print as pprust}; -use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; @@ -128,13 +128,66 @@ struct CollectItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } -impl<'a, 'tcx, 'v> Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> { - fn visit_item(&mut self, item: &hir::Item) { - convert_item(self.ccx, item); +impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> { + /// Collect item types is structured into two tasks. The outer + /// task, `CollectItem`, walks the entire content of an item-like + /// thing, including its body. It also spawns an inner task, + /// `CollectItemSig`, which walks only the signature. This inner + /// task is the one that writes the item-type into the various + /// maps. This setup ensures that the item body is never + /// accessible to the task that computes its signature, so that + /// changes to the body don't affect the signature. + /// + /// Consider an example function `foo` that also has a closure in its body: + /// + /// ``` + /// fn foo() { + /// ... + /// let bar = || ...; // we'll label this closure as "bar" below + /// } + /// ``` + /// + /// This results in a dep-graph like so. I've labeled the edges to + /// document where they arise. + /// + /// ``` + /// [HirBody(foo)] -2--> [CollectItem(foo)] -4-> [ItemSignature(bar)] + /// ^ ^ + /// 1 3 + /// [Hir(foo)] -----------+-6-> [CollectItemSig(foo)] -5-> [ItemSignature(foo)] + /// ``` + /// + /// 1. This is added by the `visit_all_item_likes_in_krate`. + /// 2. This is added when we fetch the item body. + /// 3. This is added because `CollectItem` launches `CollectItemSig`. + /// - it is arguably false; if we refactor the `with_task` system; + /// we could get probably rid of it, but it is also harmless enough. + /// 4. This is added by the code in `visit_expr` when we write to `item_types`. + /// 5. This is added by the code in `convert_item` when we write to `item_types`; + /// note that this write occurs inside the `CollectItemSig` task. + /// 6. Added by explicit `read` below + fn with_collect_item_sig(&self, id: ast::NodeId, op: OP) + where OP: FnOnce() + { + let def_id = self.ccx.tcx.map.local_def_id(id); + self.ccx.tcx.dep_graph.with_task(DepNode::CollectItemSig(def_id), || { + self.ccx.tcx.map.read(id); + op(); + }); + } +} + +impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.ccx.tcx.map) + } + + fn visit_item(&mut self, item: &'tcx hir::Item) { + self.with_collect_item_sig(item.id, || convert_item(self.ccx, item)); intravisit::walk_item(self, item); } - fn visit_expr(&mut self, expr: &hir::Expr) { + fn visit_expr(&mut self, expr: &'tcx hir::Expr) { if let hir::ExprClosure(..) = expr.node { let def_id = self.ccx.tcx.map.local_def_id(expr.id); generics_of_def_id(self.ccx, def_id); @@ -143,7 +196,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> { intravisit::walk_expr(self, expr); } - fn visit_ty(&mut self, ty: &hir::Ty) { + fn visit_ty(&mut self, ty: &'tcx hir::Ty) { if let hir::TyImplTrait(..) = ty.node { let def_id = self.ccx.tcx.map.local_def_id(ty.id); generics_of_def_id(self.ccx, def_id); @@ -151,8 +204,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> { intravisit::walk_ty(self, ty); } - fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) { - convert_impl_item(self.ccx, impl_item); + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { + self.with_collect_item_sig(impl_item.id, || { + convert_impl_item(self.ccx, impl_item) + }); intravisit::walk_impl_item(self, impl_item); } } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 9f29319430dd5..009330065f3c2 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -489,8 +489,8 @@ impl<'a, 'hir> HirCollector<'a, 'hir> { } impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { - fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'hir>> { - Some(self.map) + fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'hir> { + intravisit::NestedVisitorMap::All(&self.map) } fn visit_item(&mut self, item: &'hir hir::Item) { diff --git a/src/test/incremental/change_private_impl_method_cc/struct_point.rs b/src/test/incremental/change_private_impl_method_cc/struct_point.rs index bb7f7025c5905..4d9ca77969bd7 100644 --- a/src/test/incremental/change_private_impl_method_cc/struct_point.rs +++ b/src/test/incremental/change_private_impl_method_cc/struct_point.rs @@ -23,9 +23,8 @@ #![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")] #![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")] -// FIXME(#37720) these two should be reused, but data gets entangled across crates -#![rustc_partition_translated(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")] -#![rustc_partition_translated(module="struct_point-fn_calls_methods_in_another_impl", cfg="rpass2")] +#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")] +#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="rpass2")] extern crate point; @@ -33,8 +32,7 @@ extern crate point; mod fn_calls_methods_in_same_impl { use point::Point; - // FIXME(#37720) data gets entangled across crates - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -45,8 +43,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_methods_in_another_impl { use point::Point; - // FIXME(#37720) data gets entangled across crates - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] pub fn dirty() { let mut x = Point { x: 2.0, y: 2.0 }; x.translate(3.0, 3.0); diff --git a/src/test/incremental/change_pub_inherent_method_body/struct_point.rs b/src/test/incremental/change_pub_inherent_method_body/struct_point.rs index 665eafb4f4eeb..e0047e5ec6455 100644 --- a/src/test/incremental/change_pub_inherent_method_body/struct_point.rs +++ b/src/test/incremental/change_pub_inherent_method_body/struct_point.rs @@ -19,9 +19,7 @@ #![rustc_partition_translated(module="struct_point-point", cfg="rpass2")] -// FIXME(#35078) -- this gets recompiled because we don't separate sig from body -#![rustc_partition_translated(module="struct_point-fn_calls_changed_method", cfg="rpass2")] - +#![rustc_partition_reused(module="struct_point-fn_calls_changed_method", cfg="rpass2")] #![rustc_partition_reused(module="struct_point-fn_calls_another_method", cfg="rpass2")] #![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")] #![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")] @@ -52,8 +50,7 @@ mod point { mod fn_calls_changed_method { use point::Point; - // FIXME(#35078) -- this gets recompiled because we don't separate sig from body - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.distance_from_origin(); diff --git a/src/test/incremental/hashes/call_expressions.rs b/src/test/incremental/hashes/call_expressions.rs index d2030d9355462..647ff5dedf3dd 100644 --- a/src/test/incremental/hashes/call_expressions.rs +++ b/src/test/incremental/hashes/call_expressions.rs @@ -36,9 +36,11 @@ pub fn change_callee_function() { } #[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")] pub fn change_callee_function() { callee2(1, 2) @@ -53,9 +55,11 @@ pub fn change_argument_function() { } #[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")] pub fn change_argument_function() { callee1(1, 3) @@ -70,9 +74,11 @@ mod change_callee_indirectly_function { #[cfg(not(cfail1))] use super::callee2 as callee; - #[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")] pub fn change_callee_indirectly_function() { callee(1, 2) @@ -94,9 +100,11 @@ pub fn change_callee_method() { } #[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")] pub fn change_callee_method() { let s = Struct; @@ -113,9 +121,11 @@ pub fn change_argument_method() { } #[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")] pub fn change_argument_method() { let s = Struct; @@ -132,9 +142,11 @@ pub fn change_ufcs_callee_method() { } #[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")] pub fn change_ufcs_callee_method() { let s = Struct; @@ -151,9 +163,11 @@ pub fn change_argument_method_ufcs() { } #[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")] pub fn change_argument_method_ufcs() { let s = Struct; @@ -170,9 +184,11 @@ pub fn change_to_ufcs() { } #[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")] pub fn change_to_ufcs() { let s = Struct; @@ -192,9 +208,11 @@ mod change_ufcs_callee_indirectly { #[cfg(not(cfail1))] use super::Struct2 as Struct; - #[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")] pub fn change_ufcs_callee_indirectly() { let s = Struct; diff --git a/src/test/incremental/hashes/for_loops.rs b/src/test/incremental/hashes/for_loops.rs index 7a8502f7caab1..bae3c9bf5965d 100644 --- a/src/test/incremental/hashes/for_loops.rs +++ b/src/test/incremental/hashes/for_loops.rs @@ -36,9 +36,11 @@ fn change_loop_body() { } #[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")] fn change_loop_body() { let mut _x = 0; @@ -61,9 +63,11 @@ fn change_iteration_variable_name() { } #[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")] fn change_iteration_variable_name() { let mut _x = 0; @@ -86,9 +90,11 @@ fn change_iteration_variable_pattern() { } #[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")] fn change_iteration_variable_pattern() { let mut _x = 0; @@ -111,9 +117,11 @@ fn change_iterable() { } #[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")] fn change_iterable() { let mut _x = 0; @@ -135,9 +143,11 @@ fn add_break() { } #[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")] fn add_break() { let mut _x = 0; @@ -160,9 +170,11 @@ fn add_loop_label() { } #[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")] fn add_loop_label() { let mut _x = 0; @@ -185,9 +197,11 @@ fn add_loop_label_to_break() { } #[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")] fn add_loop_label_to_break() { let mut _x = 0; @@ -212,9 +226,11 @@ fn change_break_label() { } #[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")] fn change_break_label() { let mut _x = 0; @@ -239,9 +255,11 @@ fn add_loop_label_to_continue() { } #[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")] fn add_loop_label_to_continue() { let mut _x = 0; @@ -266,9 +284,11 @@ fn change_continue_label() { } #[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")] fn change_continue_label() { let mut _x = 0; @@ -293,9 +313,11 @@ fn change_continue_to_break() { } #[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")] fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/if_expressions.rs b/src/test/incremental/hashes/if_expressions.rs index ba6289f754ede..c39eeab34c8f3 100644 --- a/src/test/incremental/hashes/if_expressions.rs +++ b/src/test/incremental/hashes/if_expressions.rs @@ -36,9 +36,11 @@ pub fn change_condition(x: bool) -> u32 { } #[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")] pub fn change_condition(x: bool) -> u32 { if !x { @@ -59,9 +61,11 @@ pub fn change_then_branch(x: bool) -> u32 { } #[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")] pub fn change_then_branch(x: bool) -> u32 { if x { @@ -84,9 +88,11 @@ pub fn change_else_branch(x: bool) -> u32 { } #[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")] pub fn change_else_branch(x: bool) -> u32 { if x { @@ -111,9 +117,11 @@ pub fn add_else_branch(x: bool) -> u32 { } #[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")] pub fn add_else_branch(x: bool) -> u32 { let mut ret = 1; @@ -139,9 +147,11 @@ pub fn change_condition_if_let(x: Option) -> u32 { } #[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")] pub fn change_condition_if_let(x: Option) -> u32 { if let Some(_) = x { @@ -164,9 +174,11 @@ pub fn change_then_branch_if_let(x: Option) -> u32 { } #[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")] pub fn change_then_branch_if_let(x: Option) -> u32 { if let Some(x) = x { @@ -189,9 +201,11 @@ pub fn change_else_branch_if_let(x: Option) -> u32 { } #[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")] pub fn change_else_branch_if_let(x: Option) -> u32 { if let Some(x) = x { @@ -216,9 +230,11 @@ pub fn add_else_branch_if_let(x: Option) -> u32 { } #[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")] pub fn add_else_branch_if_let(x: Option) -> u32 { let mut ret = 1; diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs index 7bfd8077a3da6..9e532548e11dd 100644 --- a/src/test/incremental/hashes/let_expressions.rs +++ b/src/test/incremental/hashes/let_expressions.rs @@ -32,9 +32,11 @@ pub fn change_name() { } #[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")] pub fn change_name() { let _y = 2u64; @@ -49,9 +51,11 @@ pub fn add_type() { } #[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")] pub fn add_type() { let _x: u32 = 2u32; @@ -66,9 +70,11 @@ pub fn change_type() { } #[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")] pub fn change_type() { let _x: u8 = 2; @@ -83,9 +89,11 @@ pub fn change_mutability_of_reference_type() { } #[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")] pub fn change_mutability_of_reference_type() { let _x: &mut u64; @@ -100,9 +108,11 @@ pub fn change_mutability_of_slot() { } #[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")] pub fn change_mutability_of_slot() { let _x: u64 = 0; @@ -117,9 +127,11 @@ pub fn change_simple_binding_to_pattern() { } #[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")] pub fn change_simple_binding_to_pattern() { let (_a, _b) = (0u8, 'x'); @@ -134,9 +146,11 @@ pub fn change_name_in_pattern() { } #[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")] pub fn change_name_in_pattern() { let (_a, _c) = (1u8, 'y'); @@ -151,9 +165,11 @@ pub fn add_ref_in_pattern() { } #[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")] pub fn add_ref_in_pattern() { let (ref _a, _b) = (1u8, 'y'); @@ -168,9 +184,11 @@ pub fn add_amp_in_pattern() { } #[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")] pub fn add_amp_in_pattern() { let (&_a, _b) = (&1u8, 'y'); @@ -185,9 +203,11 @@ pub fn change_mutability_of_binding_in_pattern() { } #[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")] pub fn change_mutability_of_binding_in_pattern() { let (mut _a, _b) = (99u8, 'q'); @@ -202,9 +222,11 @@ pub fn add_initializer() { } #[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")] pub fn add_initializer() { let _x: i16 = 3i16; @@ -219,9 +241,11 @@ pub fn change_initializer() { } #[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")] pub fn change_initializer() { let _x = 5u16; diff --git a/src/test/incremental/hashes/loop_expressions.rs b/src/test/incremental/hashes/loop_expressions.rs index eaa5f68b98c4b..da43ef3c461b7 100644 --- a/src/test/incremental/hashes/loop_expressions.rs +++ b/src/test/incremental/hashes/loop_expressions.rs @@ -36,9 +36,11 @@ fn change_loop_body() { } #[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")] fn change_loop_body() { let mut _x = 0; @@ -60,9 +62,11 @@ fn add_break() { } #[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")] fn add_break() { let mut _x = 0; @@ -85,9 +89,11 @@ fn add_loop_label() { } #[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")] fn add_loop_label() { let mut _x = 0; @@ -110,9 +116,11 @@ fn add_loop_label_to_break() { } #[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")] fn add_loop_label_to_break() { let mut _x = 0; @@ -137,9 +145,11 @@ fn change_break_label() { } #[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")] fn change_break_label() { let mut _x = 0; @@ -164,9 +174,11 @@ fn add_loop_label_to_continue() { } #[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")] fn add_loop_label_to_continue() { let mut _x = 0; @@ -191,9 +203,11 @@ fn change_continue_label() { } #[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")] fn change_continue_label() { let mut _x = 0; @@ -218,9 +232,11 @@ fn change_continue_to_break() { } #[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")] fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/match_expressions.rs b/src/test/incremental/hashes/match_expressions.rs index 95e94a91c5bb1..48f99b834ce17 100644 --- a/src/test/incremental/hashes/match_expressions.rs +++ b/src/test/incremental/hashes/match_expressions.rs @@ -36,9 +36,11 @@ pub fn add_arm(x: u32) -> u32 { } #[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")] pub fn add_arm(x: u32) -> u32 { match x { @@ -62,9 +64,11 @@ pub fn change_order_of_arms(x: u32) -> u32 { } #[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")] pub fn change_order_of_arms(x: u32) -> u32 { match x { @@ -87,9 +91,11 @@ pub fn add_guard_clause(x: u32, y: bool) -> u32 { } #[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")] pub fn add_guard_clause(x: u32, y: bool) -> u32 { match x { @@ -112,9 +118,11 @@ pub fn change_guard_clause(x: u32, y: bool) -> u32 { } #[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")] pub fn change_guard_clause(x: u32, y: bool) -> u32 { match x { @@ -137,9 +145,11 @@ pub fn add_at_binding(x: u32) -> u32 { } #[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")] pub fn add_at_binding(x: u32) -> u32 { match x { @@ -162,9 +172,11 @@ pub fn change_name_of_at_binding(x: u32) -> u32 { } #[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")] pub fn change_name_of_at_binding(x: u32) -> u32 { match x { @@ -186,9 +198,11 @@ pub fn change_simple_name_to_pattern(x: u32) -> u32 { } #[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")] pub fn change_simple_name_to_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -210,9 +224,11 @@ pub fn change_name_in_pattern(x: u32) -> u32 { } #[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")] pub fn change_name_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -234,9 +250,11 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 { } #[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")] pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -257,9 +275,11 @@ pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 { } #[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")] pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -280,9 +300,11 @@ pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 { } #[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")] pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 { match (&x, x & 1) { @@ -304,9 +326,11 @@ pub fn change_rhs_of_arm(x: u32) -> u32 { } #[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")] pub fn change_rhs_of_arm(x: u32) -> u32 { match x { @@ -329,9 +353,11 @@ pub fn add_alternative_to_arm(x: u32) -> u32 { } #[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")] pub fn add_alternative_to_arm(x: u32) -> u32 { match x { diff --git a/src/test/incremental/hashes/panic_exprs.rs b/src/test/incremental/hashes/panic_exprs.rs index f5f4c0042b432..5d4d434fd633f 100644 --- a/src/test/incremental/hashes/panic_exprs.rs +++ b/src/test/incremental/hashes/panic_exprs.rs @@ -34,9 +34,11 @@ pub fn indexing(slice: &[u8]) -> u8 { } #[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")] pub fn indexing(slice: &[u8]) -> u8 { slice[100] @@ -50,9 +52,11 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 { } #[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")] pub fn arithmetic_overflow_plus(val: i32) -> i32 { val + 1 @@ -66,9 +70,11 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 { } #[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")] pub fn arithmetic_overflow_minus(val: i32) -> i32 { val - 1 @@ -82,9 +88,11 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 { } #[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")] pub fn arithmetic_overflow_mult(val: i32) -> i32 { val * 2 @@ -98,9 +106,11 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 { } #[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")] pub fn arithmetic_overflow_negation(val: i32) -> i32 { -val @@ -114,9 +124,11 @@ pub fn division_by_zero(val: i32) -> i32 { } #[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")] pub fn division_by_zero(val: i32) -> i32 { 2 / val @@ -129,9 +141,11 @@ pub fn mod_by_zero(val: i32) -> i32 { } #[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")] pub fn mod_by_zero(val: i32) -> i32 { 2 % val @@ -150,6 +164,8 @@ pub fn bitwise(val: i32) -> i32 { #[cfg(not(cfail1))] #[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_clean(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn bitwise(val: i32) -> i32 { @@ -166,6 +182,8 @@ pub fn logical(val1: bool, val2: bool, val3: bool) -> bool { #[cfg(not(cfail1))] #[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_clean(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn logical(val1: bool, val2: bool, val3: bool) -> bool { diff --git a/src/test/incremental/hashes/panic_exprs_no_overflow_checks.rs b/src/test/incremental/hashes/panic_exprs_no_overflow_checks.rs index b84b7f5f378aa..b3fc8e2d36d1c 100644 --- a/src/test/incremental/hashes/panic_exprs_no_overflow_checks.rs +++ b/src/test/incremental/hashes/panic_exprs_no_overflow_checks.rs @@ -41,9 +41,11 @@ pub fn indexing(slice: &[u8]) -> u8 { } #[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")] pub fn indexing(slice: &[u8]) -> u8 { slice[100] @@ -58,9 +60,11 @@ pub fn arithmetic_overflow_plus_inherit(val: i32) -> i32 { } #[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")] #[rustc_inherit_overflow_checks] pub fn arithmetic_overflow_plus_inherit(val: i32) -> i32 { @@ -76,9 +80,11 @@ pub fn arithmetic_overflow_minus_inherit(val: i32) -> i32 { } #[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")] #[rustc_inherit_overflow_checks] pub fn arithmetic_overflow_minus_inherit(val: i32) -> i32 { @@ -94,9 +100,11 @@ pub fn arithmetic_overflow_mult_inherit(val: i32) -> i32 { } #[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")] #[rustc_inherit_overflow_checks] pub fn arithmetic_overflow_mult_inherit(val: i32) -> i32 { @@ -112,9 +120,11 @@ pub fn arithmetic_overflow_negation_inherit(val: i32) -> i32 { } #[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")] #[rustc_inherit_overflow_checks] pub fn arithmetic_overflow_negation_inherit(val: i32) -> i32 { @@ -129,9 +139,11 @@ pub fn division_by_zero(val: i32) -> i32 { } #[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")] pub fn division_by_zero(val: i32) -> i32 { 2 / val @@ -144,9 +156,11 @@ pub fn mod_by_zero(val: i32) -> i32 { } #[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")] pub fn mod_by_zero(val: i32) -> i32 { 2 % val @@ -165,6 +179,8 @@ pub fn bitwise(val: i32) -> i32 { #[cfg(not(cfail1))] #[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_clean(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn bitwise(val: i32) -> i32 { @@ -181,6 +197,8 @@ pub fn logical(val1: bool, val2: bool, val3: bool) -> bool { #[cfg(not(cfail1))] #[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_clean(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn logical(val1: bool, val2: bool, val3: bool) -> bool { @@ -196,6 +214,8 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 { #[cfg(not(cfail1))] #[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_clean(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn arithmetic_overflow_plus(val: i32) -> i32 { @@ -212,6 +232,8 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 { #[cfg(not(cfail1))] #[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_clean(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn arithmetic_overflow_minus(val: i32) -> i32 { @@ -228,6 +250,8 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 { #[cfg(not(cfail1))] #[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_clean(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn arithmetic_overflow_mult(val: i32) -> i32 { @@ -244,6 +268,8 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 { #[cfg(not(cfail1))] #[rustc_clean(label="Hir", cfg="cfail2")] #[rustc_clean(label="Hir", cfg="cfail3")] +#[rustc_clean(label="HirBody", cfg="cfail2")] +#[rustc_clean(label="HirBody", cfg="cfail3")] #[rustc_metadata_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn arithmetic_overflow_negation(val: i32) -> i32 { diff --git a/src/test/incremental/hashes/struct_constructors.rs b/src/test/incremental/hashes/struct_constructors.rs index c4366ea11e3f6..6a9f4698bf887 100644 --- a/src/test/incremental/hashes/struct_constructors.rs +++ b/src/test/incremental/hashes/struct_constructors.rs @@ -42,9 +42,11 @@ fn change_field_value_regular_struct() -> RegularStruct { } #[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")] fn change_field_value_regular_struct() -> RegularStruct { RegularStruct { @@ -67,9 +69,11 @@ fn change_field_order_regular_struct() -> RegularStruct { } #[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")] fn change_field_order_regular_struct() -> RegularStruct { RegularStruct { @@ -97,9 +101,11 @@ fn add_field_regular_struct() -> RegularStruct { } #[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")] fn add_field_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -134,9 +140,11 @@ fn change_field_label_regular_struct() -> RegularStruct { } #[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")] fn change_field_label_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -171,9 +179,11 @@ fn change_constructor_path_regular_struct() { } #[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")] fn change_constructor_path_regular_struct() { let _ = RegularStruct2 { @@ -212,9 +222,11 @@ fn change_field_value_tuple_struct() -> TupleStruct { } #[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")] fn change_field_value_tuple_struct() -> TupleStruct { TupleStruct(0, 1, 3) @@ -231,9 +243,11 @@ fn change_constructor_path_tuple_struct() { } #[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")] fn change_constructor_path_tuple_struct() { let _ = TupleStruct2(0, 1, 2); diff --git a/src/test/incremental/hashes/unary_and_binary_exprs.rs b/src/test/incremental/hashes/unary_and_binary_exprs.rs index 2c0ca0043122c..05b0dec4e7e81 100644 --- a/src/test/incremental/hashes/unary_and_binary_exprs.rs +++ b/src/test/incremental/hashes/unary_and_binary_exprs.rs @@ -32,9 +32,11 @@ pub fn const_negation() -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn const_negation() -> i32 { -1 @@ -49,9 +51,11 @@ pub fn const_bitwise_not() -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn const_bitwise_not() -> i32 { !99 @@ -66,9 +70,11 @@ pub fn var_negation(x: i32, y: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn var_negation(x: i32, y: i32) -> i32 { -y @@ -83,9 +89,11 @@ pub fn var_bitwise_not(x: i32, y: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn var_bitwise_not(x: i32, y: i32) -> i32 { !y @@ -100,9 +108,11 @@ pub fn var_deref(x: &i32, y: &i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn var_deref(x: &i32, y: &i32) -> i32 { *y @@ -117,9 +127,11 @@ pub fn first_const_add() -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn first_const_add() -> i32 { 2 + 3 @@ -134,9 +146,11 @@ pub fn second_const_add() -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn second_const_add() -> i32 { 1 + 3 @@ -151,9 +165,11 @@ pub fn first_var_add(a: i32, b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn first_var_add(a: i32, b: i32) -> i32 { b + 2 @@ -168,9 +184,11 @@ pub fn second_var_add(a: i32, b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn second_var_add(a: i32, b: i32) -> i32 { 1 + b @@ -185,9 +203,11 @@ pub fn plus_to_minus(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn plus_to_minus(a: i32) -> i32 { 1 - a @@ -202,9 +222,11 @@ pub fn plus_to_mult(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn plus_to_mult(a: i32) -> i32 { 1 * a @@ -219,9 +241,11 @@ pub fn plus_to_div(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn plus_to_div(a: i32) -> i32 { 1 / a @@ -236,9 +260,11 @@ pub fn plus_to_mod(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn plus_to_mod(a: i32) -> i32 { 1 % a @@ -253,9 +279,11 @@ pub fn and_to_or(a: bool, b: bool) -> bool { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn and_to_or(a: bool, b: bool) -> bool { a || b @@ -270,9 +298,11 @@ pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 { 1 | a @@ -287,9 +317,11 @@ pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 { 1 ^ a @@ -304,9 +336,11 @@ pub fn bitwise_and_to_lshift(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn bitwise_and_to_lshift(a: i32) -> i32 { a << 1 @@ -321,9 +355,11 @@ pub fn bitwise_and_to_rshift(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn bitwise_and_to_rshift(a: i32) -> i32 { a >> 1 @@ -338,9 +374,11 @@ pub fn eq_to_uneq(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn eq_to_uneq(a: i32) -> bool { a != 1 @@ -355,9 +393,11 @@ pub fn eq_to_lt(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn eq_to_lt(a: i32) -> bool { a < 1 @@ -372,9 +412,11 @@ pub fn eq_to_gt(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn eq_to_gt(a: i32) -> bool { a > 1 @@ -389,9 +431,11 @@ pub fn eq_to_le(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn eq_to_le(a: i32) -> bool { a <= 1 @@ -406,9 +450,11 @@ pub fn eq_to_ge(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn eq_to_ge(a: i32) -> bool { a >= 1 @@ -425,9 +471,11 @@ pub fn type_cast(a: u8) -> u64 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn type_cast(a: u8) -> u64 { let b = a as u32; @@ -444,9 +492,11 @@ pub fn value_cast(a: u32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn value_cast(a: u32) -> i32 { 2 as i32 @@ -464,9 +514,11 @@ pub fn lvalue() -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn lvalue() -> i32 { let mut x = 10; @@ -486,9 +538,11 @@ pub fn rvalue() -> i32 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn rvalue() -> i32 { let mut x = 10; @@ -505,9 +559,11 @@ pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 { } #[cfg(not(cfail1))] -#[rustc_dirty(label="Hir", cfg="cfails2")] -#[rustc_clean(label="Hir", cfg="cfails3")] -#[rustc_metadata_dirty(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_clean(cfg="cfail2")] #[rustc_metadata_clean(cfg="cfail3")] pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 { s[j] diff --git a/src/test/incremental/hashes/while_let_loops.rs b/src/test/incremental/hashes/while_let_loops.rs index 405645bd1b842..f4fd7e709b4b1 100644 --- a/src/test/incremental/hashes/while_let_loops.rs +++ b/src/test/incremental/hashes/while_let_loops.rs @@ -36,9 +36,11 @@ fn change_loop_body() { } #[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")] fn change_loop_body() { let mut _x = 0; @@ -61,9 +63,11 @@ fn change_loop_condition() { } #[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")] fn change_loop_condition() { let mut _x = 0; @@ -85,9 +89,11 @@ fn add_break() { } #[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")] fn add_break() { let mut _x = 0; @@ -110,9 +116,11 @@ fn add_loop_label() { } #[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")] fn add_loop_label() { let mut _x = 0; @@ -135,9 +143,11 @@ fn add_loop_label_to_break() { } #[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")] fn add_loop_label_to_break() { let mut _x = 0; @@ -162,9 +172,11 @@ fn change_break_label() { } #[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")] fn change_break_label() { let mut _x = 0; @@ -189,9 +201,11 @@ fn add_loop_label_to_continue() { } #[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")] fn add_loop_label_to_continue() { let mut _x = 0; @@ -216,9 +230,11 @@ fn change_continue_label() { } #[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")] fn change_continue_label() { let mut _x = 0; @@ -243,9 +259,11 @@ fn change_continue_to_break() { } #[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")] fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/while_loops.rs b/src/test/incremental/hashes/while_loops.rs index f16611ee463e0..aa70d7e9fc112 100644 --- a/src/test/incremental/hashes/while_loops.rs +++ b/src/test/incremental/hashes/while_loops.rs @@ -36,9 +36,11 @@ fn change_loop_body() { } #[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")] fn change_loop_body() { let mut _x = 0; @@ -61,9 +63,11 @@ fn change_loop_condition() { } #[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")] fn change_loop_condition() { let mut _x = 0; @@ -85,9 +89,11 @@ fn add_break() { } #[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")] fn add_break() { let mut _x = 0; @@ -110,9 +116,11 @@ fn add_loop_label() { } #[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")] fn add_loop_label() { let mut _x = 0; @@ -135,9 +143,11 @@ fn add_loop_label_to_break() { } #[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")] fn add_loop_label_to_break() { let mut _x = 0; @@ -162,9 +172,11 @@ fn change_break_label() { } #[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")] fn change_break_label() { let mut _x = 0; @@ -189,9 +201,11 @@ fn add_loop_label_to_continue() { } #[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")] fn add_loop_label_to_continue() { let mut _x = 0; @@ -216,9 +230,11 @@ fn change_continue_label() { } #[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")] fn change_continue_label() { let mut _x = 0; @@ -243,9 +259,11 @@ fn change_continue_to_break() { } #[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")] fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hello_world.rs b/src/test/incremental/hello_world.rs index a06c25ac055c7..b7f90c09b565c 100644 --- a/src/test/incremental/hello_world.rs +++ b/src/test/incremental/hello_world.rs @@ -18,12 +18,12 @@ fn main() { } mod x { #[cfg(rpass1)] - pub fn x() -> i32 { + pub fn xxxx() -> i32 { 1 } #[cfg(rpass2)] - pub fn x() -> i32 { + pub fn xxxx() -> i32 { 2 } } @@ -31,9 +31,9 @@ mod x { mod y { use x; - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] - pub fn y() { - x::x(); + #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + pub fn yyyy() { + x::xxxx(); } } @@ -42,6 +42,6 @@ mod z { #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] pub fn z() { - y::y(); + y::yyyy(); } } diff --git a/src/test/incremental/ich_method_call_trait_scope.rs b/src/test/incremental/ich_method_call_trait_scope.rs index f28ecf74dd47d..0a36e3c693edb 100644 --- a/src/test/incremental/ich_method_call_trait_scope.rs +++ b/src/test/incremental/ich_method_call_trait_scope.rs @@ -46,12 +46,14 @@ mod mod3 { mod mod3 { use Trait2; - #[rustc_dirty(label="Hir", cfg="rpass2")] + #[rustc_clean(label="Hir", cfg="rpass2")] + #[rustc_dirty(label="HirBody", cfg="rpass2")] fn bar() { ().method(); } #[rustc_clean(label="Hir", cfg="rpass2")] + #[rustc_clean(label="HirBody", cfg="rpass2")] fn baz() { 22; // no method call, traits in scope don't matter } diff --git a/src/test/incremental/ich_nested_items.rs b/src/test/incremental/ich_nested_items.rs index 4466cfb1317d9..e8e40d57b1ee6 100644 --- a/src/test/incremental/ich_nested_items.rs +++ b/src/test/incremental/ich_nested_items.rs @@ -23,11 +23,14 @@ fn foo() { #[cfg(rpass2)] #[rustc_clean(label="Hir", cfg="rpass2")] +#[rustc_clean(label="HirBody", cfg="rpass2")] fn foo() { #[rustc_clean(label="Hir", cfg="rpass2")] + #[rustc_clean(label="HirBody", cfg="rpass2")] fn baz() { } // order is different... #[rustc_clean(label="Hir", cfg="rpass2")] + #[rustc_clean(label="HirBody", cfg="rpass2")] fn bar() { } // but that doesn't matter. fn bap() { } // neither does adding a new item diff --git a/src/test/incremental/ich_resolve_results.rs b/src/test/incremental/ich_resolve_results.rs index 680a91da09f92..49a88c530ff64 100644 --- a/src/test/incremental/ich_resolve_results.rs +++ b/src/test/incremental/ich_resolve_results.rs @@ -45,11 +45,13 @@ mod mod3 { use test; #[rustc_clean(label="Hir", cfg="rpass2")] + #[rustc_clean(label="HirBody", cfg="rpass2")] fn in_expr() { Foo(0); } #[rustc_clean(label="Hir", cfg="rpass2")] + #[rustc_clean(label="HirBody", cfg="rpass2")] fn in_type() { test::(); } @@ -60,12 +62,14 @@ mod mod3 { use test; use mod2::Foo; // <-- This changed! - #[rustc_dirty(label="Hir", cfg="rpass3")] + #[rustc_clean(label="Hir", cfg="rpass3")] + #[rustc_dirty(label="HirBody", cfg="rpass3")] fn in_expr() { Foo(0); } - #[rustc_dirty(label="Hir", cfg="rpass3")] + #[rustc_clean(label="Hir", cfg="rpass3")] + #[rustc_dirty(label="HirBody", cfg="rpass3")] fn in_type() { test::(); } diff --git a/src/test/incremental/source_loc_macros.rs b/src/test/incremental/source_loc_macros.rs index f922ac0da41b1..36d1b3ecbcd14 100644 --- a/src/test/incremental/source_loc_macros.rs +++ b/src/test/incremental/source_loc_macros.rs @@ -18,16 +18,19 @@ #![feature(rustc_attrs)] #[rustc_clean(label="Hir", cfg="rpass2")] +#[rustc_clean(label="HirBody", cfg="rpass2")] fn line_same() { let _ = line!(); } #[rustc_clean(label="Hir", cfg="rpass2")] +#[rustc_clean(label="HirBody", cfg="rpass2")] fn col_same() { let _ = column!(); } #[rustc_clean(label="Hir", cfg="rpass2")] +#[rustc_clean(label="HirBody", cfg="rpass2")] fn file_same() { let _ = file!(); } @@ -38,7 +41,8 @@ fn line_different() { } #[cfg(rpass2)] -#[rustc_dirty(label="Hir", cfg="rpass2")] +#[rustc_clean(label="Hir", cfg="rpass2")] +#[rustc_dirty(label="HirBody", cfg="rpass2")] fn line_different() { let _ = line!(); } @@ -49,7 +53,8 @@ fn col_different() { } #[cfg(rpass2)] -#[rustc_dirty(label="Hir", cfg="rpass2")] +#[rustc_clean(label="Hir", cfg="rpass2")] +#[rustc_dirty(label="HirBody", cfg="rpass2")] fn col_different() { let _ = column!(); } diff --git a/src/test/incremental/spans_insignificant_w_o_debuginfo.rs b/src/test/incremental/spans_insignificant_w_o_debuginfo.rs index 9c8b8552498c4..90ec4a9d55831 100644 --- a/src/test/incremental/spans_insignificant_w_o_debuginfo.rs +++ b/src/test/incremental/spans_insignificant_w_o_debuginfo.rs @@ -22,4 +22,5 @@ pub fn main() {} #[cfg(rpass2)] #[rustc_clean(label="Hir", cfg="rpass2")] +#[rustc_clean(label="HirBody", cfg="rpass2")] pub fn main() {} diff --git a/src/test/incremental/spans_significant_w_debuginfo.rs b/src/test/incremental/spans_significant_w_debuginfo.rs index b0920aa1fa510..cdab8de9828ab 100644 --- a/src/test/incremental/spans_significant_w_debuginfo.rs +++ b/src/test/incremental/spans_significant_w_debuginfo.rs @@ -22,4 +22,5 @@ pub fn main() {} #[cfg(rpass2)] #[rustc_dirty(label="Hir", cfg="rpass2")] +#[rustc_dirty(label="HirBody", cfg="rpass2")] pub fn main() {} diff --git a/src/test/run-pass/associated-const-const-eval.rs b/src/test/run-pass/associated-const-const-eval.rs new file mode 100644 index 0000000000000..0b230df41469f --- /dev/null +++ b/src/test/run-pass/associated-const-const-eval.rs @@ -0,0 +1,30 @@ +// Copyright 2015 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. + +#![feature(associated_consts)] + +trait Foo { + const NUM: usize; +} + +impl Foo for i32 { + const NUM: usize = 1; +} + +const FOO: usize = ::NUM; + +fn main() { + assert_eq!(1, FOO); + + match 1 { + ::NUM => {}, + _ => assert!(false) + } +} diff --git a/src/test/run-pass/associated-const-cross-crate-const-eval.rs b/src/test/run-pass/associated-const-cross-crate-const-eval.rs new file mode 100644 index 0000000000000..7d31bb5b1a5e2 --- /dev/null +++ b/src/test/run-pass/associated-const-cross-crate-const-eval.rs @@ -0,0 +1,38 @@ +// Copyright 2015 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. + +// aux-build:associated-const-cc-lib.rs + +#![feature(associated_consts)] + +extern crate associated_const_cc_lib as foolib; + +pub struct LocalFoo; + +impl foolib::Foo for LocalFoo { + const BAR: usize = 1; +} + +const FOO_1: usize = ::BAR; +const FOO_2: usize = ::BAR; +const FOO_3: usize = foolib::InherentBar::BAR; + +fn main() { + assert_eq!(0, FOO_1); + assert_eq!(1, FOO_2); + assert_eq!(3, FOO_3); + + match 0 { + ::BAR => {}, + ::BAR => assert!(false), + foolib::InherentBar::BAR => assert!(false), + _ => assert!(false) + } +}