diff --git a/src/librustc/front/map/blocks.rs b/src/librustc/front/map/blocks.rs index e6c165193f032..0e24a4446fbe9 100644 --- a/src/librustc/front/map/blocks.rs +++ b/src/librustc/front/map/blocks.rs @@ -29,7 +29,7 @@ use rustc_front::hir::{Block, FnDecl}; use syntax::ast::{Name, NodeId}; use rustc_front::hir as ast; use syntax::codemap::Span; -use rustc_front::visit::FnKind; +use rustc_front::intravisit::FnKind; /// An FnLikeNode is a Node that is like a fn, in that it has a decl /// and a body (as well as a NodeId, a span, etc). diff --git a/src/librustc/front/map/collector.rs b/src/librustc/front/map/collector.rs index 54e2563a123ba..e98e88c9abf24 100644 --- a/src/librustc/front/map/collector.rs +++ b/src/librustc/front/map/collector.rs @@ -13,7 +13,7 @@ use super::MapEntry::*; use rustc_front::hir::*; use rustc_front::util; -use rustc_front::visit::{self, Visitor}; +use rustc_front::intravisit::{self, Visitor}; use middle::def_id::{CRATE_DEF_INDEX, DefIndex}; use std::iter::repeat; use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; @@ -22,14 +22,16 @@ use syntax::codemap::Span; /// A Visitor that walks over an AST and collects Node's into an AST /// Map. pub struct NodeCollector<'ast> { + pub krate: &'ast Crate, pub map: Vec>, pub definitions: Definitions, pub parent_node: NodeId, } impl<'ast> NodeCollector<'ast> { - pub fn root() -> NodeCollector<'ast> { + pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> { let mut collector = NodeCollector { + krate: krate, map: vec![], definitions: Definitions::new(), parent_node: CRATE_NODE_ID, @@ -44,13 +46,15 @@ impl<'ast> NodeCollector<'ast> { collector } - pub fn extend(parent: &'ast InlinedParent, + pub fn extend(krate: &'ast Crate, + parent: &'ast InlinedParent, parent_node: NodeId, parent_def_path: DefPath, map: Vec>, definitions: Definitions) -> NodeCollector<'ast> { let mut collector = NodeCollector { + krate: krate, map: map, parent_node: parent_node, definitions: definitions, @@ -107,6 +111,13 @@ impl<'ast> NodeCollector<'ast> { } impl<'ast> Visitor<'ast> for NodeCollector<'ast> { + /// Because we want to track parent items and so forth, enable + /// deep walking so that we walk nested items in the context of + /// their outer items. + fn visit_nested_item(&mut self, item: ItemId) { + self.visit_item(self.krate.item(item.id)) + } + fn visit_item(&mut self, i: &'ast Item) { // Pick the def data. This need not be unique, but the more // information we encapsulate into @@ -173,7 +184,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } _ => {} } - visit::walk_item(self, i); + intravisit::walk_item(self, i); self.parent_node = parent_node; } @@ -184,7 +195,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { let parent_node = self.parent_node; self.parent_node = foreign_item.id; - visit::walk_foreign_item(self, foreign_item); + intravisit::walk_foreign_item(self, foreign_item); self.parent_node = parent_node; } @@ -195,7 +206,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { DefPathData::TypeParam(ty_param.name)); } - visit::walk_generics(self, generics); + intravisit::walk_generics(self, generics); } fn visit_trait_item(&mut self, ti: &'ast TraitItem) { @@ -217,7 +228,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { _ => { } } - visit::walk_trait_item(self, ti); + intravisit::walk_trait_item(self, ti); self.parent_node = parent_node; } @@ -240,7 +251,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { _ => { } } - visit::walk_impl_item(self, ii); + intravisit::walk_impl_item(self, ii); self.parent_node = parent_node; } @@ -259,7 +270,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { let parent_node = self.parent_node; self.parent_node = pat.id; - visit::walk_pat(self, pat); + intravisit::walk_pat(self, pat); self.parent_node = parent_node; } @@ -273,7 +284,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { let parent_node = self.parent_node; self.parent_node = expr.id; - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); self.parent_node = parent_node; } @@ -282,21 +293,21 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.insert(id, NodeStmt(stmt)); let parent_node = self.parent_node; self.parent_node = id; - visit::walk_stmt(self, stmt); + intravisit::walk_stmt(self, stmt); self.parent_node = parent_node; } - fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl, + fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, b: &'ast Block, s: Span, id: NodeId) { assert_eq!(self.parent_node, id); - visit::walk_fn(self, fk, fd, b, s); + intravisit::walk_fn(self, fk, fd, b, s); } fn visit_block(&mut self, block: &'ast Block) { self.insert(block.id, NodeBlock(block)); let parent_node = self.parent_node; self.parent_node = block.id; - visit::walk_block(self, block); + intravisit::walk_block(self, block); self.parent_node = parent_node; } diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs index fb883c0ca0c08..6ee6b07059751 100644 --- a/src/librustc/front/map/mod.rs +++ b/src/librustc/front/map/mod.rs @@ -25,7 +25,7 @@ use syntax::parse::token; use rustc_front::hir::*; use rustc_front::fold::Folder; -use rustc_front::visit; +use rustc_front::intravisit; use rustc_front::print::pprust; use arena::TypedArena; @@ -809,9 +809,11 @@ impl Folder for IdAndSpanUpdater { } pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> { - let mut collector = NodeCollector::root(); - visit::walk_crate(&mut collector, &forest.krate); - let NodeCollector { map, definitions, .. } = collector; + let (map, definitions) = { + let mut collector = NodeCollector::root(&forest.krate); + intravisit::walk_crate(&mut collector, &forest.krate); + (collector.map, collector.definitions) + }; if log_enabled!(::log::DEBUG) { // This only makes sense for ordered stores; note the @@ -847,7 +849,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, -> &'ast InlinedItem { let mut fld = IdAndSpanUpdater { fold_ops: fold_ops }; let ii = match ii { - II::Item(i) => II::Item(fld.fold_item(i)), + II::Item(i) => II::Item(i.map(|i| fld.fold_item(i))), II::TraitItem(d, ti) => { II::TraitItem(fld.fold_ops.new_def_id(d), fld.fold_trait_item(ti)) @@ -867,6 +869,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let ii_parent_id = fld.new_id(DUMMY_NODE_ID); let mut collector = NodeCollector::extend( + map.krate(), ii_parent, ii_parent_id, def_path, diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index e3eac2e606807..798f4866d346c 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -44,7 +44,7 @@ use syntax::parse::token::InternedString; use syntax::ast; use rustc_front::hir; use rustc_front::util; -use rustc_front::visit as hir_visit; +use rustc_front::intravisit as hir_visit; use syntax::visit as ast_visit; use syntax::diagnostic; @@ -555,7 +555,6 @@ impl<'a> EarlyContext<'a> { { let mut v = ast_util::IdVisitor { operation: self, - pass_through_items: false, visited_outermost: false, }; f(&mut v); @@ -583,11 +582,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { fn visit_ids(&mut self, f: F) where F: FnOnce(&mut util::IdVisitor) { - let mut v = util::IdVisitor { - operation: self, - pass_through_items: false, - visited_outermost: false, - }; + let mut v = util::IdVisitor::new(self); f(&mut v); } } @@ -611,10 +606,12 @@ impl<'a, 'tcx> LintContext for LateContext<'a, 'tcx> { } fn enter_attrs(&mut self, attrs: &[ast::Attribute]) { + debug!("late context: enter_attrs({:?})", attrs); run_lints!(self, enter_lint_attrs, late_passes, attrs); } fn exit_attrs(&mut self, attrs: &[ast::Attribute]) { + debug!("late context: exit_attrs({:?})", attrs); run_lints!(self, exit_lint_attrs, late_passes, attrs); } } @@ -638,15 +635,24 @@ impl<'a> LintContext for EarlyContext<'a> { } fn enter_attrs(&mut self, attrs: &[ast::Attribute]) { + debug!("early context: exit_attrs({:?})", attrs); run_lints!(self, enter_lint_attrs, early_passes, attrs); } fn exit_attrs(&mut self, attrs: &[ast::Attribute]) { + debug!("early context: exit_attrs({:?})", attrs); run_lints!(self, exit_lint_attrs, early_passes, attrs); } } impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> 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 visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.tcx.map.expect_item(item.id)) + } + fn visit_item(&mut self, it: &hir::Item) { self.with_lint_attrs(&it.attrs, |cx| { run_lints!(cx, check_item, late_passes, it); @@ -952,6 +958,7 @@ impl<'a, 'tcx> IdVisitingOperation for LateContext<'a, 'tcx> { match self.sess().lints.borrow_mut().remove(&id) { None => {} Some(lints) => { + debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints); for (lint_id, span, msg) in lints { self.span_lint(lint_id.lint, span, &msg[..]) } @@ -1008,16 +1015,14 @@ impl LateLintPass for GatherNodeLevels { /// /// Consumes the `lint_store` field of the `Session`. pub fn check_crate(tcx: &ty::ctxt, - krate: &hir::Crate, exported_items: &ExportedItems) { - + let krate = tcx.map.krate(); let mut cx = LateContext::new(tcx, krate, exported_items); // Visit the whole crate. cx.with_lint_attrs(&krate.attrs, |cx| { cx.visit_id(ast::CRATE_NODE_ID); cx.visit_ids(|v| { - v.visited_outermost = true; hir_visit::walk_crate(v, krate); }); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 14c11af6f3863..23be6117f190f 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -34,7 +34,7 @@ pub use self::LintSource::*; use std::hash; use std::ascii::AsciiExt; use syntax::codemap::Span; -use rustc_front::visit::FnKind; +use rustc_front::intravisit::FnKind; use syntax::visit as ast_visit; use syntax::ast; use rustc_front::hir; @@ -218,7 +218,7 @@ pub type EarlyLintPassObject = Box; pub type LateLintPassObject = Box; /// Identifies a lint known to the compiler. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct LintId { // Identity is based on pointer equality of this field. lint: &'static Lint, diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 6c81562f7b291..9c2aa584aabce 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -37,7 +37,7 @@ use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::parse::token::InternedString; use syntax::util::small_vector::SmallVector; -use rustc_front::visit; +use rustc_front::intravisit::Visitor; use rustc_front::hir; use log; @@ -53,10 +53,9 @@ pub struct CrateReader<'a> { foreign_item_map: FnvHashMap>, } -impl<'a, 'b, 'v> visit::Visitor<'v> for LocalCrateReader<'a, 'b> { - fn visit_item(&mut self, a: &hir::Item) { +impl<'a, 'b, 'hir> Visitor<'hir> for LocalCrateReader<'a, 'b> { + fn visit_item(&mut self, a: &'hir hir::Item) { self.process_item(a); - visit::walk_item(self, a); } } @@ -716,7 +715,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { // etc. pub fn read_crates(&mut self, krate: &hir::Crate) { self.process_crate(krate); - visit::walk_crate(self, krate); + krate.visit_all_items(self); self.creader.inject_allocator_crate(); if log_enabled!(log::INFO) { diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index bfdbb6dadd43c..e543d8708b571 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -46,8 +46,8 @@ use syntax; use rbml::writer::Encoder; use rustc_front::hir; -use rustc_front::visit::Visitor; -use rustc_front::visit; +use rustc_front::intravisit::Visitor; +use rustc_front::intravisit; use front::map::{LinkedPath, PathElem, PathElems}; use front::map as ast_map; @@ -431,11 +431,12 @@ fn encode_info_for_mod(ecx: &EncodeContext, debug!("(encoding info for module) encoding info for module ID {}", id); // Encode info about all the module children. - for item in &md.items { + for item_id in &md.item_ids { rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(ecx.tcx.map.local_def_id(item.id))); + def_to_u64(ecx.tcx.map.local_def_id(item_id.id))); - each_auxiliary_node_id(&**item, |auxiliary_node_id| { + let item = ecx.tcx.map.expect_item(item_id.id); + each_auxiliary_node_id(item, |auxiliary_node_id| { rbml_w.wr_tagged_u64(tag_mod_child, def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id))); true @@ -1468,25 +1469,26 @@ struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { index: &'a mut CrateIndex<'tcx>, } -impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> { - fn visit_expr(&mut self, ex: &hir::Expr) { - visit::walk_expr(self, ex); +impl<'a, 'b, 'c, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'c, 'tcx> { + fn visit_expr(&mut self, ex: &'tcx hir::Expr) { + intravisit::walk_expr(self, ex); my_visit_expr(ex, self.rbml_w_for_visit_item, self.ecx, self.index); } - fn visit_item(&mut self, i: &hir::Item) { - visit::walk_item(self, i); + fn visit_item(&mut self, i: &'tcx hir::Item) { + intravisit::walk_item(self, i); my_visit_item(i, self.rbml_w_for_visit_item, self.ecx, self.index); } - fn visit_foreign_item(&mut self, ni: &hir::ForeignItem) { - visit::walk_foreign_item(self, ni); + fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { + intravisit::walk_foreign_item(self, ni); my_visit_foreign_item(ni, self.rbml_w_for_visit_item, self.ecx, self.index); } } fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, - rbml_w: &mut Encoder, - krate: &hir::Crate) + rbml_w: &mut Encoder) -> CrateIndex<'tcx> { + let krate = ecx.tcx.map.krate(); + let mut index = CrateIndex { items: IndexData::new(ecx.tcx.map.num_local_def_ids()), xrefs: FnvHashMap() @@ -1503,11 +1505,11 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, syntax::parse::token::intern(&ecx.link_meta.crate_name), hir::Public); - visit::walk_crate(&mut EncodeVisitor { + krate.visit_all_items(&mut EncodeVisitor { index: &mut index, ecx: ecx, rbml_w_for_visit_item: &mut *rbml_w, - }, krate); + }); rbml_w.end_tag(); index @@ -1735,7 +1737,7 @@ fn encode_struct_field_attrs(ecx: &EncodeContext, } rbml_w.start_tag(tag_struct_fields); - visit::walk_crate(&mut StructFieldVisitor { ecx: ecx, rbml_w: rbml_w }, krate); + krate.visit_all_items(&mut StructFieldVisitor { ecx: ecx, rbml_w: rbml_w }); rbml_w.end_tag(); } @@ -1756,7 +1758,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> { .push(impl_id); } } - visit::walk_item(self, item); } } @@ -1768,7 +1769,7 @@ fn encode_impls<'a>(ecx: &'a EncodeContext, tcx: ecx.tcx, impls: FnvHashMap() }; - visit::walk_crate(&mut visitor, krate); + krate.visit_all_items(&mut visitor); rbml_w.start_tag(tag_impls); for (trait_, trait_impls) in visitor.impls { @@ -1787,11 +1788,12 @@ fn encode_misc_info(ecx: &EncodeContext, rbml_w: &mut Encoder) { rbml_w.start_tag(tag_misc_info); rbml_w.start_tag(tag_misc_info_crate_items); - for item in &krate.module.items { + for item_id in &krate.module.item_ids { rbml_w.wr_tagged_u64(tag_mod_child, - def_to_u64(ecx.tcx.map.local_def_id(item.id))); + def_to_u64(ecx.tcx.map.local_def_id(item_id.id))); - each_auxiliary_node_id(&**item, |auxiliary_node_id| { + let item = ecx.tcx.map.expect_item(item_id.id); + each_auxiliary_node_id(item, |auxiliary_node_id| { rbml_w.wr_tagged_u64(tag_mod_child, def_to_u64(ecx.tcx.map.local_def_id(auxiliary_node_id))); true @@ -2022,7 +2024,7 @@ fn encode_metadata_inner(wr: &mut Cursor>, // Encode and index the items. rbml_w.start_tag(tag_items); i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap(); - let index = encode_info_for_items(&ecx, &mut rbml_w, krate); + let index = encode_info_for_items(&ecx, &mut rbml_w); stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; rbml_w.end_tag(); diff --git a/src/librustc/metadata/inline.rs b/src/librustc/metadata/inline.rs index a5ca68e4350eb..e621a4166d719 100644 --- a/src/librustc/metadata/inline.rs +++ b/src/librustc/metadata/inline.rs @@ -13,7 +13,7 @@ use rustc_front::hir; use rustc_front::util::IdVisitor; use syntax::ast_util::{IdRange, IdRangeComputingVisitor, IdVisitingOperation}; use syntax::ptr::P; -use rustc_front::visit::Visitor; +use rustc_front::intravisit::Visitor; use self::InlinedItem::*; /// The data we save and restore about an inlined item or method. This is not @@ -48,11 +48,7 @@ impl InlinedItem { } pub fn visit_ids(&self, operation: &mut O) { - let mut id_visitor = IdVisitor { - operation: operation, - pass_through_items: true, - visited_outermost: false, - }; + let mut id_visitor = IdVisitor::new(operation); self.visit(&mut id_visitor); } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index a92fe1a0f2b5b..752fdc2347411 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -389,7 +389,7 @@ fn simplify_ast(ii: InlinedItemRef) -> InlinedItem { match ii { // HACK we're not dropping items. InlinedItemRef::Item(i) => { - InlinedItem::Item(fold::noop_fold_item(P(i.clone()), &mut fld)) + InlinedItem::Item(P(fold::noop_fold_item(i.clone(), &mut fld))) } InlinedItemRef::TraitItem(d, ti) => { InlinedItem::TraitItem(d, fold::noop_fold_trait_item(P(ti.clone()), &mut fld)) @@ -1393,13 +1393,13 @@ fn mk_ctxt() -> parse::ParseSess { } #[cfg(test)] -fn roundtrip(in_item: P) { +fn roundtrip(in_item: hir::Item) { let mut wr = Cursor::new(Vec::new()); - encode_item_ast(&mut Encoder::new(&mut wr), &*in_item); + encode_item_ast(&mut Encoder::new(&mut wr), &in_item); let rbml_doc = rbml::Doc::new(wr.get_ref()); let out_item = decode_item_ast(rbml_doc); - assert!(*in_item == out_item); + assert!(in_item == out_item); } #[test] @@ -1449,11 +1449,11 @@ fn test_simplification() { let hir_item = lower_item(&lcx, &item); let item_in = InlinedItemRef::Item(&hir_item); let item_out = simplify_ast(item_in); - let item_exp = InlinedItem::Item(lower_item(&lcx, "e_item!(&cx, + let item_exp = InlinedItem::Item(P(lower_item(&lcx, "e_item!(&cx, fn new_int_alist() -> alist { return alist {eq_fn: eq_int, data: Vec::new()}; } - ).unwrap())); + ).unwrap()))); match (item_out, item_exp) { (InlinedItem::Item(item_out), InlinedItem::Item(item_exp)) => { assert!(pprust::item_to_string(&*item_out) == diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 814c7c990bd6a..e29cc04e65a1b 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -41,7 +41,7 @@ use rustc_front::hir; use syntax::ast; use syntax::codemap::Span; use syntax::feature_gate::UnstableFeatures; -use rustc_front::visit::{self, FnKind, Visitor}; +use rustc_front::intravisit::{self, FnKind, Visitor}; use std::collections::hash_map::Entry; use std::cmp::Ordering; @@ -81,7 +81,7 @@ bitflags! { } } -#[derive(Copy, Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] enum Mode { Const, ConstFn, @@ -190,7 +190,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { let qualif = self.with_mode(mode, |this| { this.with_euv(Some(fn_id), |euv| euv.walk_fn(fd, b)); - visit::walk_fn(this, fk, fd, b, s); + intravisit::walk_fn(this, fk, fd, b, s); this.qualif }); @@ -308,6 +308,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { fn visit_item(&mut self, i: &hir::Item) { debug!("visit_item(item={})", self.tcx.map.node_to_string(i.id)); + assert_eq!(self.mode, Mode::Var); match i.node { hir::ItemStatic(_, hir::MutImmutable, ref expr) => { self.check_static_type(&**expr); @@ -328,7 +329,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { } } _ => { - self.with_mode(Mode::Var, |v| visit::walk_item(v, i)); + intravisit::walk_item(self, i); } } } @@ -339,10 +340,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { if let Some(ref expr) = *default { self.global_expr(Mode::Const, &*expr); } else { - visit::walk_trait_item(self, t); + intravisit::walk_trait_item(self, t); } } - _ => self.with_mode(Mode::Var, |v| visit::walk_trait_item(v, t)), + _ => self.with_mode(Mode::Var, |v| intravisit::walk_trait_item(v, t)), } } @@ -351,7 +352,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { hir::ImplItemKind::Const(_, ref expr) => { self.global_expr(Mode::Const, &*expr); } - _ => self.with_mode(Mode::Var, |v| visit::walk_impl_item(v, i)), + _ => self.with_mode(Mode::Var, |v| intravisit::walk_impl_item(v, i)), } } @@ -386,7 +387,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { } } } - _ => visit::walk_pat(self, p) + _ => intravisit::walk_pat(self, p) } } @@ -412,7 +413,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { tail expressions", self.msg()); } } - visit::walk_block(self, block); + intravisit::walk_block(self, block); } fn visit_expr(&mut self, ex: &hir::Expr) { @@ -464,11 +465,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { if let Some(mutbl) = borrow { self.record_borrow(discr.id, mutbl); } - visit::walk_expr(self, ex); + intravisit::walk_expr(self, ex); } // Division by zero and overflow checking. hir::ExprBinary(op, _, _) => { - visit::walk_expr(self, ex); + intravisit::walk_expr(self, ex); let div_or_rem = op.node == hir::BiDiv || op.node == hir::BiRem; match node_ty.sty { ty::TyUint(_) | ty::TyInt(_) if div_or_rem => { @@ -487,7 +488,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { _ => {} } } - _ => visit::walk_expr(self, ex) + _ => intravisit::walk_expr(self, ex) } // Handle borrows on (or inside the autorefs of) this expression. @@ -837,12 +838,12 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp } pub fn check_crate(tcx: &ty::ctxt) { - visit::walk_crate(&mut CheckCrateVisitor { + tcx.map.krate().visit_all_items(&mut CheckCrateVisitor { tcx: tcx, mode: Mode::Var, qualif: ConstQualif::NOT_CONST, rvalue_borrows: NodeMap() - }, tcx.map.krate()); + }); tcx.sess.abort_if_errors(); } diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index 1e85190ef38fa..22e9df63d0185 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -12,8 +12,7 @@ use self::Context::*; use session::Session; use syntax::codemap::Span; -use rustc_front::visit::Visitor; -use rustc_front::visit; +use rustc_front::intravisit::{self, Visitor}; use rustc_front::hir; #[derive(Clone, Copy, PartialEq)] @@ -28,12 +27,12 @@ struct CheckLoopVisitor<'a> { } pub fn check_crate(sess: &Session, krate: &hir::Crate) { - visit::walk_crate(&mut CheckLoopVisitor { sess: sess, cx: Normal }, krate) + krate.visit_all_items(&mut CheckLoopVisitor { sess: sess, cx: Normal }); } impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> { fn visit_item(&mut self, i: &hir::Item) { - self.with_context(Normal, |v| visit::walk_item(v, i)); + self.with_context(Normal, |v| intravisit::walk_item(v, i)); } fn visit_expr(&mut self, e: &hir::Expr) { @@ -50,7 +49,7 @@ impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> { } hir::ExprBreak(_) => self.require_loop("break", e.span), hir::ExprAgain(_) => self.require_loop("continue", e.span), - _ => visit::walk_expr(self, e) + _ => intravisit::walk_expr(self, e) } } } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index f46e55e244140..3e6cf07d86f0b 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -33,7 +33,7 @@ use std::iter::{FromIterator, IntoIterator, repeat}; use rustc_front::hir; use rustc_front::hir::Pat; -use rustc_front::visit::{self, Visitor, FnKind}; +use rustc_front::intravisit::{self, Visitor, FnKind}; use rustc_front::util as front_util; use rustc_back::slice; @@ -155,15 +155,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> { } pub fn check_crate(tcx: &ty::ctxt) { - visit::walk_crate(&mut MatchCheckCtxt { + tcx.map.krate().visit_all_items(&mut MatchCheckCtxt { tcx: tcx, param_env: tcx.empty_parameter_environment(), - }, tcx.map.krate()); + }); tcx.sess.abort_if_errors(); } fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) { - visit::walk_expr(cx, ex); + intravisit::walk_expr(cx, ex); match ex.node { hir::ExprMatch(ref scrut, ref arms, source) => { for arm in arms { @@ -485,11 +485,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { renaming_map: renaming_map, }; - let mut id_visitor = front_util::IdVisitor { - operation: &mut renaming_recorder, - pass_through_items: true, - visited_outermost: false, - }; + let mut id_visitor = front_util::IdVisitor::new(&mut renaming_recorder); id_visitor.visit_expr(const_expr); } @@ -990,7 +986,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], } fn check_local(cx: &mut MatchCheckCtxt, loc: &hir::Local) { - visit::walk_local(cx, loc); + intravisit::walk_local(cx, loc); let pat = StaticInliner::new(cx.tcx, None).fold_pat(loc.pat.clone()); check_irrefutable(cx, &pat, false); @@ -1011,7 +1007,7 @@ fn check_fn(cx: &mut MatchCheckCtxt, _ => cx.param_env = ParameterEnvironment::for_item(cx.tcx, fn_id), } - visit::walk_fn(cx, kind, decl, body, sp); + intravisit::walk_fn(cx, kind, decl, body, sp); for input in &decl.inputs { check_irrefutable(cx, &input.pat, true); @@ -1191,10 +1187,10 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> { hir::PatIdent(_, _, Some(_)) => { let bindings_were_allowed = self.bindings_allowed; self.bindings_allowed = false; - visit::walk_pat(self, pat); + intravisit::walk_pat(self, pat); self.bindings_allowed = bindings_were_allowed; } - _ => visit::walk_pat(self, pat), + _ => intravisit::walk_pat(self, pat), } } } diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index 5659a18e500d9..35adeae3e617c 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -20,21 +20,21 @@ use middle::ty; use syntax::ast; use rustc_front::hir; use syntax::codemap::Span; -use rustc_front::visit; +use rustc_front::intravisit; pub fn check_crate(tcx: &ty::ctxt, krate: &hir::Crate) { let mut rvcx = RvalueContext { tcx: tcx }; - visit::walk_crate(&mut rvcx, krate); + krate.visit_all_items(&mut rvcx); } struct RvalueContext<'a, 'tcx: 'a> { tcx: &'a ty::ctxt<'tcx>, } -impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { +impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for RvalueContext<'a, 'tcx> { fn visit_fn(&mut self, - fk: visit::FnKind<'v>, + fk: intravisit::FnKind<'v>, fd: &'v hir::FnDecl, b: &'v hir::Block, s: Span, @@ -50,7 +50,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, b); } - visit::walk_fn(self, fk, fd, b, s) + intravisit::walk_fn(self, fk, fd, b, s) } } diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs index ede37eb737f83..85a3117196acf 100644 --- a/src/librustc/middle/check_static_recursion.rs +++ b/src/librustc/middle/check_static_recursion.rs @@ -19,8 +19,7 @@ use util::nodemap::NodeMap; use syntax::{ast}; use syntax::codemap::Span; use syntax::feature_gate::{GateIssue, emit_feature_err}; -use rustc_front::visit::Visitor; -use rustc_front::visit; +use rustc_front::intravisit::{self, Visitor}; use rustc_front::hir; use std::cell::RefCell; @@ -60,7 +59,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> { } _ => {} } - visit::walk_item(self, it) + intravisit::walk_item(self, it) } fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) { @@ -74,7 +73,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> { } _ => {} } - visit::walk_trait_item(self, ti) + intravisit::walk_trait_item(self, ti) } fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) { @@ -86,7 +85,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> { } _ => {} } - visit::walk_impl_item(self, ii) + intravisit::walk_impl_item(self, ii) } } @@ -100,7 +99,7 @@ pub fn check_crate<'ast>(sess: &Session, ast_map: ast_map, discriminant_map: RefCell::new(NodeMap()), }; - visit::walk_crate(&mut visitor, krate); + krate.visit_all_items(&mut visitor); sess.abort_if_errors(); } @@ -197,13 +196,13 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> { impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { fn visit_item(&mut self, it: &'ast hir::Item) { - self.with_item_id_pushed(it.id, |v| visit::walk_item(v, it)); + self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it)); } fn visit_enum_def(&mut self, enum_definition: &'ast hir::EnumDef, generics: &'ast hir::Generics, item_id: ast::NodeId, _: Span) { self.populate_enum_discriminants(enum_definition); - visit::walk_enum_def(self, enum_definition, generics, item_id); + intravisit::walk_enum_def(self, enum_definition, generics, item_id); } fn visit_variant(&mut self, variant: &'ast hir::Variant, @@ -222,16 +221,16 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { // If `maybe_expr` is `None`, that's because no discriminant is // specified that affects this variant. Thus, no risk of recursion. if let Some(expr) = maybe_expr { - self.with_item_id_pushed(expr.id, |v| visit::walk_expr(v, expr)); + self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr)); } } fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) { - self.with_item_id_pushed(ti.id, |v| visit::walk_trait_item(v, ti)); + self.with_item_id_pushed(ti.id, |v| intravisit::walk_trait_item(v, ti)); } fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) { - self.with_item_id_pushed(ii.id, |v| visit::walk_impl_item(v, ii)); + self.with_item_id_pushed(ii.id, |v| intravisit::walk_impl_item(v, ii)); } fn visit_expr(&mut self, e: &'ast hir::Expr) { @@ -285,6 +284,6 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { }, _ => () } - visit::walk_expr(self, e); + intravisit::walk_expr(self, e); } } diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 832baa1515ffb..039c62a904c9b 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -29,7 +29,7 @@ use util::nodemap::NodeMap; use syntax::{ast, abi}; use rustc_front::hir::Expr; use rustc_front::hir; -use rustc_front::visit::FnKind; +use rustc_front::intravisit::FnKind; use syntax::codemap::Span; use syntax::parse::token::InternedString; use syntax::ptr::P; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index caedc811842a0..9abab6e04e025 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -27,7 +27,7 @@ use syntax::print::pp; use syntax::print::pprust::PrintState; use util::nodemap::NodeMap; use rustc_front::hir; -use rustc_front::visit; +use rustc_front::intravisit; use rustc_front::print::pprust; @@ -194,11 +194,11 @@ fn build_nodeid_to_index(decl: Option<&hir::FnDecl>, index: &'a mut NodeMap>, } let mut formals = Formals { entry: entry, index: index }; - visit::walk_fn_decl(&mut formals, decl); - impl<'a, 'v> visit::Visitor<'v> for Formals<'a> { + intravisit::walk_fn_decl(&mut formals, decl); + impl<'a, 'v> intravisit::Visitor<'v> for Formals<'a> { fn visit_pat(&mut self, p: &hir::Pat) { self.index.entry(p.id).or_insert(vec![]).push(self.entry); - visit::walk_pat(self, p) + intravisit::walk_pat(self, p) } } } @@ -533,7 +533,7 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> { fn pretty_print_to<'b>(&self, wr: Box, blk: &hir::Block) -> io::Result<()> { - let mut ps = pprust::rust_printer_annotated(wr, self); + let mut ps = pprust::rust_printer_annotated(wr, self, None); try!(ps.cbox(pprust::indent_unit)); try!(ps.ibox(0)); try!(ps.print_block(blk)); diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 5892067ab08fe..6dfddce9bfed8 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -14,7 +14,7 @@ use front::map as ast_map; use rustc_front::hir; -use rustc_front::visit::{self, Visitor}; +use rustc_front::intravisit::{self, Visitor}; use middle::{def, pat_util, privacy, ty}; use middle::def_id::{DefId}; @@ -182,29 +182,29 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { .contains(&attr::ReprExtern) }); - visit::walk_item(self, &*item); + intravisit::walk_item(self, &*item); } hir::ItemEnum(..) => { self.inherited_pub_visibility = item.vis == hir::Public; - visit::walk_item(self, &*item); + intravisit::walk_item(self, &*item); } hir::ItemFn(..) | hir::ItemTy(..) | hir::ItemStatic(..) | hir::ItemConst(..) => { - visit::walk_item(self, &*item); + intravisit::walk_item(self, &*item); } _ => () } } ast_map::NodeTraitItem(trait_item) => { - visit::walk_trait_item(self, trait_item); + intravisit::walk_trait_item(self, trait_item); } ast_map::NodeImplItem(impl_item) => { - visit::walk_impl_item(self, impl_item); + intravisit::walk_impl_item(self, impl_item); } ast_map::NodeForeignItem(foreign_item) => { - visit::walk_foreign_item(self, &*foreign_item); + intravisit::walk_foreign_item(self, &*foreign_item); } _ => () } @@ -227,7 +227,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { }); self.live_symbols.extend(live_fields.map(|f| f.node.id)); - visit::walk_struct_def(self, def); + intravisit::walk_struct_def(self, def); } fn visit_expr(&mut self, expr: &hir::Expr) { @@ -244,7 +244,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { _ => () } - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); } fn visit_arm(&mut self, arm: &hir::Arm) { @@ -257,10 +257,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { // can't be reached unless the variant is constructed elsewhere. let len = self.ignore_variant_stack.len(); self.ignore_variant_stack.push_all(&*variants); - visit::walk_arm(self, arm); + intravisit::walk_arm(self, arm); self.ignore_variant_stack.truncate(len); } else { - visit::walk_arm(self, arm); + intravisit::walk_arm(self, arm); } } @@ -278,23 +278,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { } self.ignore_non_const_paths = true; - visit::walk_pat(self, pat); + intravisit::walk_pat(self, pat); self.ignore_non_const_paths = false; } fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) { self.lookup_and_handle_definition(&id); - visit::walk_path(self, path); + intravisit::walk_path(self, path); } fn visit_path_list_item(&mut self, path: &hir::Path, item: &hir::PathListItem) { self.lookup_and_handle_definition(&item.node.id()); - visit::walk_path_list_item(self, path, item); - } - - fn visit_item(&mut self, _: &hir::Item) { - // Do not recurse into items. These items will be added to the - // worklist and recursed into manually if necessary. + intravisit::walk_path_list_item(self, path, item); } } @@ -371,7 +366,6 @@ impl<'v> Visitor<'v> for LifeSeeder { } _ => () } - visit::walk_item(self, item); } } @@ -408,7 +402,7 @@ fn create_and_seed_worklist(tcx: &ty::ctxt, let mut life_seeder = LifeSeeder { worklist: worklist }; - visit::walk_crate(&mut life_seeder, krate); + krate.visit_all_items(&mut life_seeder); return life_seeder.worklist; } @@ -530,6 +524,14 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { } impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { + /// Walk nested items in place so that we don't report dead-code + /// 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 visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.tcx.map.expect_item(item.id)) + } + fn visit_item(&mut self, item: &hir::Item) { if self.should_warn_about_item(item) { self.warn_dead_code( @@ -540,7 +542,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { ); } else { // Only continue if we didn't warn - visit::walk_item(self, item); + intravisit::walk_item(self, item); } } @@ -549,7 +551,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { self.warn_dead_code(variant.node.data.id(), variant.span, variant.node.name, "variant"); } else { - visit::walk_variant(self, variant, g, id); + intravisit::walk_variant(self, variant, g, id); } } @@ -557,7 +559,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { if !self.symbol_is_live(fi.id, None) { self.warn_dead_code(fi.id, fi.span, fi.name, fi.node.descriptive_variant()); } - visit::walk_foreign_item(self, fi); + intravisit::walk_foreign_item(self, fi); } fn visit_struct_field(&mut self, field: &hir::StructField) { @@ -566,7 +568,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { field.node.name().unwrap(), "struct field"); } - visit::walk_struct_field(self, field); + intravisit::walk_struct_field(self, field); } fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) { @@ -576,14 +578,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { self.warn_dead_code(impl_item.id, impl_item.span, impl_item.name, "associated const"); } - visit::walk_expr(self, expr) + intravisit::walk_expr(self, expr) } hir::ImplItemKind::Method(_, ref body) => { if !self.symbol_is_live(impl_item.id, None) { self.warn_dead_code(impl_item.id, impl_item.span, impl_item.name, "method"); } - visit::walk_block(self, body) + intravisit::walk_block(self, body) } hir::ImplItemKind::Type(..) => {} } @@ -593,10 +595,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) { match trait_item.node { hir::ConstTraitItem(_, Some(ref expr)) => { - visit::walk_expr(self, expr) + intravisit::walk_expr(self, expr) } hir::MethodTraitItem(_, Some(ref body)) => { - visit::walk_block(self, body) + intravisit::walk_block(self, body) } hir::ConstTraitItem(_, None) | hir::MethodTraitItem(_, None) | @@ -612,5 +614,5 @@ pub fn check_crate(tcx: &ty::ctxt, let live_symbols = find_live(tcx, exported_items, reachable_symbols, krate); let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols }; - visit::walk_crate(&mut visitor, krate); + intravisit::walk_crate(&mut visitor, krate); } diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index f849580871c84..822faae772611 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -19,8 +19,8 @@ use middle::ty::MethodCall; use syntax::ast; use syntax::codemap::Span; use rustc_front::hir; -use rustc_front::visit; -use rustc_front::visit::{FnKind, Visitor}; +use rustc_front::intravisit; +use rustc_front::intravisit::{FnKind, Visitor}; #[derive(Copy, Clone)] struct UnsafeContext { @@ -94,7 +94,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { self.unsafe_context = UnsafeContext::new(SafeContext) } - visit::walk_fn(self, fn_kind, fn_decl, block, span); + intravisit::walk_fn(self, fn_kind, fn_decl, block, span); self.unsafe_context = old_unsafe_context } @@ -133,7 +133,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock => {} } - visit::walk_block(self, block); + intravisit::walk_block(self, block); self.unsafe_context = old_unsafe_context } @@ -177,7 +177,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { _ => {} } - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); } } @@ -187,5 +187,5 @@ pub fn check_crate(tcx: &ty::ctxt) { unsafe_context: UnsafeContext::new(SafeContext), }; - visit::walk_crate(&mut visitor, tcx.map.krate()); + tcx.map.krate().visit_all_items(&mut visitor); } diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 3cfcb52f9030f..ecf16aaed836a 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -10,20 +10,19 @@ use front::map as ast_map; +use middle::def_id::{CRATE_DEF_INDEX}; use session::{config, Session}; use syntax::ast::NodeId; use syntax::attr; use syntax::codemap::Span; use syntax::entry::EntryPointType; use rustc_front::hir::{Item, ItemFn}; -use rustc_front::visit; -use rustc_front::visit::Visitor; +use rustc_front::intravisit::Visitor; -struct EntryContext<'a> { +struct EntryContext<'a, 'tcx: 'a> { session: &'a Session, - // The current depth in the ast - depth: usize, + map: &'a ast_map::Map<'tcx>, // The top-level function called 'main' main_fn: Option<(NodeId, Span)>, @@ -39,11 +38,12 @@ struct EntryContext<'a> { non_main_fns: Vec<(NodeId, Span)> , } -impl<'a, 'v> Visitor<'v> for EntryContext<'a> { - fn visit_item(&mut self, item: &Item) { - self.depth += 1; - find_item(item, self); - self.depth -= 1; +impl<'a, 'tcx> Visitor<'tcx> for EntryContext<'a, 'tcx> { + fn visit_item(&mut self, item: &'tcx Item) { + let def_id = self.map.local_def_id(item.id); + let def_key = self.map.def_key(def_id); + let at_root = def_key.parent == Some(CRATE_DEF_INDEX); + find_item(item, self, at_root); } } @@ -64,21 +64,21 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) { let mut ctxt = EntryContext { session: session, - depth: 0, + map: ast_map, main_fn: None, attr_main_fn: None, start_fn: None, non_main_fns: Vec::new(), }; - visit::walk_crate(&mut ctxt, ast_map.krate()); + ast_map.krate().visit_all_items(&mut ctxt); configure_main(&mut ctxt); } // Beware, this is duplicated in libsyntax/entry.rs, make sure to keep // them in sync. -fn entry_point_type(item: &Item, depth: usize) -> EntryPointType { +fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType { match item.node { ItemFn(..) => { if attr::contains_name(&item.attrs, "start") { @@ -86,7 +86,7 @@ fn entry_point_type(item: &Item, depth: usize) -> EntryPointType { } else if attr::contains_name(&item.attrs, "main") { EntryPointType::MainAttr } else if item.name.as_str() == "main" { - if depth == 1 { + if at_root { // This is a top-level function so can be 'main' EntryPointType::MainNamed } else { @@ -101,8 +101,8 @@ fn entry_point_type(item: &Item, depth: usize) -> EntryPointType { } -fn find_item(item: &Item, ctxt: &mut EntryContext) { - match entry_point_type(item, ctxt.depth) { +fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) { + match entry_point_type(item, at_root) { EntryPointType::MainNamed => { if ctxt.main_fn.is_none() { ctxt.main_fn = Some((item.id, item.span)); @@ -132,8 +132,6 @@ fn find_item(item: &Item, ctxt: &mut EntryContext) { }, EntryPointType::None => () } - - visit::walk_item(ctxt, item); } fn configure_main(this: &mut EntryContext) { diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index b3e287f6d7d5d..11a28c0b5ea9a 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -19,7 +19,7 @@ use std::fmt; use syntax::abi::RustIntrinsic; use syntax::ast; use syntax::codemap::Span; -use rustc_front::visit::{self, Visitor, FnKind}; +use rustc_front::intravisit::{self, Visitor, FnKind}; use rustc_front::hir; pub fn check_crate(tcx: &ctxt) { @@ -29,7 +29,7 @@ pub fn check_crate(tcx: &ctxt) { dummy_sized_ty: tcx.types.isize, dummy_unsized_ty: tcx.mk_slice(tcx.types.isize), }; - visit::walk_crate(&mut visitor, tcx.map.krate()); + tcx.map.krate().visit_all_items(&mut visitor); } struct IntrinsicCheckingVisitor<'a, 'tcx: 'a> { @@ -222,11 +222,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> { FnKind::ItemFn(..) | FnKind::Method(..) => { let param_env = ty::ParameterEnvironment::for_item(self.tcx, id); self.param_envs.push(param_env); - visit::walk_fn(self, fk, fd, b, s); + intravisit::walk_fn(self, fk, fd, b, s); self.param_envs.pop(); } FnKind::Closure(..) => { - visit::walk_fn(self, fk, fd, b, s); + intravisit::walk_fn(self, fk, fd, b, s); } } @@ -255,7 +255,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> { } } - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 03c75fc6cc370..a37f62e52b819 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -33,8 +33,7 @@ use syntax::ast; use syntax::attr::AttrMetaMethods; use syntax::codemap::{DUMMY_SP, Span}; use syntax::parse::token::InternedString; -use rustc_front::visit::Visitor; -use rustc_front::visit; +use rustc_front::intravisit::Visitor; use rustc_front::hir; use std::iter::Enumerate; @@ -164,8 +163,6 @@ impl<'a, 'v, 'tcx> Visitor<'v> for LanguageItemCollector<'a, 'tcx> { self.collect_item(item_index, self.ast_map.local_def_id(item.id), item.span) } } - - visit::walk_item(self, item); } } @@ -202,7 +199,7 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { } pub fn collect_local_language_items(&mut self, krate: &hir::Crate) { - visit::walk_crate(self, krate); + krate.visit_all_items(self); } pub fn collect_external_language_items(&mut self) { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index b25ad66fd1fa5..9b18b79d26155 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -127,7 +127,7 @@ use syntax::ptr::P; use rustc_front::hir::Expr; use rustc_front::hir; use rustc_front::print::pprust::{expr_to_string, block_to_string}; -use rustc_front::visit::{self, Visitor, FnKind}; +use rustc_front::intravisit::{self, Visitor, FnKind}; /// For use with `propagate_through_loop`. enum LoopKind<'a> { @@ -192,7 +192,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> { } pub fn check_crate(tcx: &ty::ctxt) { - visit::walk_crate(&mut IrMaps::new(tcx), tcx.map.krate()); + tcx.map.krate().visit_all_items(&mut IrMaps::new(tcx)); tcx.sess.abort_if_errors(); } @@ -390,7 +390,7 @@ fn visit_fn(ir: &mut IrMaps, // gather up the various local variables, significant expressions, // and so forth: - visit::walk_fn(&mut fn_maps, fk, decl, body, sp); + intravisit::walk_fn(&mut fn_maps, fk, decl, body, sp); // Special nodes and variables: // - exit_ln represents the end of the fn, either by return or panic @@ -423,7 +423,7 @@ fn visit_local(ir: &mut IrMaps, local: &hir::Local) { name: name })); }); - visit::walk_local(ir, local); + intravisit::walk_local(ir, local); } fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) { @@ -439,7 +439,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) { })); }) } - visit::walk_arm(ir, arm); + intravisit::walk_arm(ir, arm); } fn visit_expr(ir: &mut IrMaps, expr: &Expr) { @@ -451,7 +451,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { if let DefLocal(..) = def { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); } - visit::walk_expr(ir, expr); + intravisit::walk_expr(ir, expr); } hir::ExprClosure(..) => { // Interesting control flow (for loops can contain labeled @@ -474,17 +474,17 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { }); ir.set_captures(expr.id, call_caps); - visit::walk_expr(ir, expr); + intravisit::walk_expr(ir, expr); } // live nodes required for interesting control flow: hir::ExprIf(..) | hir::ExprMatch(..) | hir::ExprWhile(..) | hir::ExprLoop(..) => { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); - visit::walk_expr(ir, expr); + intravisit::walk_expr(ir, expr); } hir::ExprBinary(op, _, _) if ::rustc_front::util::lazy_binop(op.node) => { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); - visit::walk_expr(ir, expr); + intravisit::walk_expr(ir, expr); } // otherwise, live nodes are not required: @@ -497,7 +497,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { hir::ExprStruct(..) | hir::ExprRepeat(..) | hir::ExprInlineAsm(..) | hir::ExprBox(..) | hir::ExprRange(..) => { - visit::walk_expr(ir, expr); + intravisit::walk_expr(ir, expr); } } } @@ -1383,7 +1383,7 @@ fn check_local(this: &mut Liveness, local: &hir::Local) { } } - visit::walk_local(this, local); + intravisit::walk_local(this, local); } fn check_arm(this: &mut Liveness, arm: &hir::Arm) { @@ -1393,7 +1393,7 @@ fn check_arm(this: &mut Liveness, arm: &hir::Arm) { this.arm_pats_bindings(arm.pats.first().map(|p| &**p), |this, ln, var, sp, id| { this.warn_about_unused(sp, id, ln, var); }); - visit::walk_arm(this, arm); + intravisit::walk_arm(this, arm); } fn check_expr(this: &mut Liveness, expr: &Expr) { @@ -1401,13 +1401,13 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { hir::ExprAssign(ref l, _) => { this.check_lvalue(&**l); - visit::walk_expr(this, expr); + intravisit::walk_expr(this, expr); } hir::ExprAssignOp(_, ref l, _) => { this.check_lvalue(&**l); - visit::walk_expr(this, expr); + intravisit::walk_expr(this, expr); } hir::ExprInlineAsm(ref ia) => { @@ -1421,7 +1421,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { this.visit_expr(&**out); } - visit::walk_expr(this, expr); + intravisit::walk_expr(this, expr); } // no correctness conditions related to liveness @@ -1435,7 +1435,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { hir::ExprStruct(..) | hir::ExprRepeat(..) | hir::ExprClosure(..) | hir::ExprPath(..) | hir::ExprBox(..) | hir::ExprRange(..) => { - visit::walk_expr(this, expr); + intravisit::walk_expr(this, expr); } } } @@ -1532,7 +1532,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { _ => { // For other kinds of lvalues, no checks are required, // and any embedded expressions are actually rvalues - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); } } } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index e5bc9030fc97d..86237a2321a72 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -28,8 +28,8 @@ use syntax::abi; use syntax::ast; use syntax::attr; use rustc_front::hir; -use rustc_front::visit::Visitor; -use rustc_front::visit; +use rustc_front::intravisit::Visitor; +use rustc_front::intravisit; // Returns true if the given set of generics implies that the item it's // associated with must be inlined. @@ -87,9 +87,7 @@ struct ReachableContext<'a, 'tcx: 'a> { } impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { - fn visit_expr(&mut self, expr: &hir::Expr) { - match expr.node { hir::ExprPath(..) => { let def = match self.tcx.def_map.borrow().get(&expr.id) { @@ -138,12 +136,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { _ => {} } - visit::walk_expr(self, expr) - } - - fn visit_item(&mut self, _item: &hir::Item) { - // Do not recurse into items. These items will be added to the worklist - // and recursed into manually if necessary. + intravisit::walk_expr(self, expr) } } @@ -260,7 +253,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { match item.node { hir::ItemFn(_, _, _, _, _, ref search_block) => { if item_might_be_inlined(&*item) { - visit::walk_block(self, &**search_block) + intravisit::walk_block(self, &**search_block) } } @@ -292,7 +285,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { self.visit_expr(&*expr); } hir::MethodTraitItem(_, Some(ref body)) => { - visit::walk_block(self, body); + intravisit::walk_block(self, body); } hir::TypeTraitItem(..) => {} } @@ -305,7 +298,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { hir::ImplItemKind::Method(ref sig, ref body) => { let did = self.tcx.map.get_parent_did(search_item); if method_might_be_inlined(self.tcx, sig, impl_item, did) { - visit::walk_block(self, body) + intravisit::walk_block(self, body) } } hir::ImplItemKind::Type(_) => {} @@ -350,8 +343,6 @@ impl<'a, 'v> Visitor<'v> for CollectPrivateImplItemsVisitor<'a> { } } } - - visit::walk_item(self, item); } } @@ -381,8 +372,7 @@ pub fn find_reachable(tcx: &ty::ctxt, exported_items: exported_items, worklist: &mut reachable_context.worklist, }; - - visit::walk_crate(&mut collect_private_impl_items, tcx.map.krate()); + tcx.map.krate().visit_all_items(&mut collect_private_impl_items); } // Step 2: Mark all symbols that the symbols on the worklist touch. diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 1027bbf67037b..45b8ac4a16dae 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -30,7 +30,7 @@ use syntax::codemap::{self, Span}; use syntax::ast::{self, NodeId}; use rustc_front::hir; -use rustc_front::visit::{self, Visitor, FnKind}; +use rustc_front::intravisit::{self, Visitor, FnKind}; use rustc_front::hir::{Block, Item, FnDecl, Arm, Pat, Stmt, Expr, Local}; use rustc_front::util::stmt_id; @@ -696,7 +696,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &hir::Block) { { // This block should be kept approximately in sync with - // `visit::walk_block`. (We manually walk the block, rather + // `intravisit::walk_block`. (We manually walk the block, rather // than call `walk_block`, in order to maintain precise // index information.) @@ -735,7 +735,7 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) { visitor.terminating_scopes.insert(expr.id); } - visit::walk_arm(visitor, arm); + intravisit::walk_arm(visitor, arm); } fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) { @@ -750,7 +750,7 @@ fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) { _ => { } } - visit::walk_pat(visitor, pat); + intravisit::walk_pat(visitor, pat); } fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) { @@ -767,7 +767,7 @@ fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) { let prev_parent = visitor.cx.parent; visitor.cx.parent = stmt_extent; - visit::walk_stmt(visitor, stmt); + intravisit::walk_stmt(visitor, stmt); visitor.cx.parent = prev_parent; } @@ -844,7 +844,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &hir::Expr) { } } - visit::walk_expr(visitor, expr); + intravisit::walk_expr(visitor, expr); visitor.cx = prev_cx; } @@ -935,7 +935,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) { None => { } } - visit::walk_local(visitor, local); + intravisit::walk_local(visitor, local); /// True if `pat` match the `P&` nonterminal: /// @@ -1080,7 +1080,7 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &hir::Item) { var_parent: ROOT_CODE_EXTENT, parent: ROOT_CODE_EXTENT }; - visit::walk_item(visitor, item); + intravisit::walk_item(visitor, item); visitor.create_item_scope_if_needed(item.id); visitor.cx = prev_cx; visitor.terminating_scopes = prev_ts; @@ -1119,8 +1119,8 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor, var_parent: fn_decl_scope, }; - visit::walk_fn_decl(visitor, decl); - visit::walk_fn_kind(visitor, kind); + intravisit::walk_fn_decl(visitor, decl); + intravisit::walk_fn_kind(visitor, kind); // The body of the every fn is a root scope. visitor.cx = Context { @@ -1181,12 +1181,12 @@ impl<'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> { } fn visit_impl_item(&mut self, ii: &hir::ImplItem) { - visit::walk_impl_item(self, ii); + intravisit::walk_impl_item(self, ii); self.create_item_scope_if_needed(ii.id); } fn visit_trait_item(&mut self, ti: &hir::TraitItem) { - visit::walk_trait_item(self, ti); + intravisit::walk_trait_item(self, ti); self.create_item_scope_if_needed(ti.id); } @@ -1237,7 +1237,7 @@ pub fn resolve_crate(sess: &Session, krate: &hir::Crate) -> RegionMaps { }, terminating_scopes: NodeSet() }; - visit::walk_crate(&mut visitor, krate); + krate.visit_all_items(&mut visitor); } return maps; } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index fa0c6c41ce5cc..1452cf2cd7667 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -32,7 +32,7 @@ use util::nodemap::NodeMap; use rustc_front::hir; use rustc_front::print::pprust::lifetime_to_string; -use rustc_front::visit::{self, Visitor, FnKind}; +use rustc_front::intravisit::{self, Visitor, FnKind}; #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] pub enum DefRegion { @@ -95,30 +95,28 @@ static ROOT_SCOPE: ScopeChain<'static> = RootScope; pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegionMap { let mut named_region_map = NodeMap(); - visit::walk_crate(&mut LifetimeContext { + krate.visit_all_items(&mut LifetimeContext { sess: sess, named_region_map: &mut named_region_map, scope: &ROOT_SCOPE, def_map: def_map, trait_ref_hack: false, labels_in_fn: vec![], - }, krate); + }); sess.abort_if_errors(); named_region_map } impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { fn visit_item(&mut self, item: &hir::Item) { - // Items save/restore the set of labels. This way inner items - // can freely reuse names, be they loop labels or lifetimes. - let saved = replace(&mut self.labels_in_fn, vec![]); + assert!(self.labels_in_fn.is_empty()); // Items always introduce a new root scope self.with(RootScope, |_, this| { match item.node { hir::ItemFn(..) => { // Fn lifetimes get added in visit_fn below: - visit::walk_item(this, item); + intravisit::walk_item(this, item); } hir::ItemExternCrate(_) | hir::ItemUse(_) | @@ -128,7 +126,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { hir::ItemStatic(..) | hir::ItemConst(..) => { // These sorts of items have no lifetime parameters at all. - visit::walk_item(this, item); + intravisit::walk_item(this, item); } hir::ItemTy(_, ref generics) | hir::ItemEnum(_, ref generics) | @@ -140,14 +138,14 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { let early_scope = EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE); this.with(early_scope, |old_scope, this| { this.check_lifetime_defs(old_scope, lifetimes); - visit::walk_item(this, item); + intravisit::walk_item(this, item); }); } } }); - // Done traversing the item; restore saved set of labels. - replace(&mut self.labels_in_fn, saved); + // Done traversing the item; remove any labels it created + self.labels_in_fn.truncate(0); } fn visit_foreign_item(&mut self, item: &hir::ForeignItem) { @@ -160,11 +158,11 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { match item.node { hir::ForeignItemFn(_, ref generics) => { this.visit_early_late(subst::FnSpace, generics, |this| { - visit::walk_foreign_item(this, item); + intravisit::walk_foreign_item(this, item); }) } hir::ForeignItemStatic(..) => { - visit::walk_foreign_item(this, item); + intravisit::walk_foreign_item(this, item); } } }); @@ -199,7 +197,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { // a bare fn has no bounds, so everything // contained within is scoped within its binder. this.check_lifetime_defs(old_scope, &c.lifetimes); - visit::walk_ty(this, ty); + intravisit::walk_ty(this, ty); }); } hir::TyPath(None, ref path) => { @@ -212,12 +210,12 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { }); } _ => { - visit::walk_ty(self, ty); + intravisit::walk_ty(self, ty); } } } _ => { - visit::walk_ty(self, ty) + intravisit::walk_ty(self, ty) } } } @@ -230,9 +228,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { if let hir::MethodTraitItem(ref sig, None) = trait_item.node { self.visit_early_late( subst::FnSpace, &sig.generics, - |this| visit::walk_trait_item(this, trait_item)) + |this| intravisit::walk_trait_item(this, trait_item)) } else { - visit::walk_trait_item(self, trait_item); + intravisit::walk_trait_item(self, trait_item); } replace(&mut self.labels_in_fn, saved); @@ -241,7 +239,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { fn visit_block(&mut self, b: &hir::Block) { self.with(BlockScope(region::DestructionScopeData::new(b.id), self.scope), - |_, this| visit::walk_block(this, b)); + |_, this| intravisit::walk_block(this, b)); } fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) { @@ -317,7 +315,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { for lifetime in &trait_ref.bound_lifetimes { this.visit_lifetime_def(lifetime); } - visit::walk_path(this, &trait_ref.trait_ref.path) + intravisit::walk_path(this, &trait_ref.trait_ref.path) }) } else { self.visit_trait_ref(&trait_ref.trait_ref) @@ -417,7 +415,7 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) { self.labels_in_fn.push((label, ex.span)); } - visit::walk_expr(self, ex) + intravisit::walk_expr(self, ex) } fn visit_item(&mut self, _: &hir::Item) { @@ -463,7 +461,7 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) { } impl<'a> LifetimeContext<'a> { - // This is just like visit::walk_fn, except that it extracts the + // This is just like intravisit::walk_fn, except that it extracts the // labels of the function body and swaps them in before visiting // the function body itself. fn walk_fn<'b>(&mut self, @@ -473,16 +471,16 @@ impl<'a> LifetimeContext<'a> { _span: Span) { match fk { FnKind::ItemFn(_, generics, _, _, _, _) => { - visit::walk_fn_decl(self, fd); + intravisit::walk_fn_decl(self, fd); self.visit_generics(generics); } FnKind::Method(_, sig, _) => { - visit::walk_fn_decl(self, fd); + intravisit::walk_fn_decl(self, fd); self.visit_generics(&sig.generics); self.visit_explicit_self(&sig.explicit_self); } FnKind::Closure(..) => { - visit::walk_fn_decl(self, fd); + intravisit::walk_fn_decl(self, fd); } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 02e1c7739c4e4..2ba66807d4ecc 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -31,7 +31,7 @@ use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap}; use rustc_front::hir; use rustc_front::hir::{Block, Crate, Item, Generics, StructField, Variant}; -use rustc_front::visit::{self, Visitor}; +use rustc_front::intravisit::{self, Visitor}; use std::mem::replace; use std::cmp::Ordering; @@ -174,6 +174,13 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { } impl<'a, 'tcx, 'v> Visitor<'v> 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 visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.tcx.map.expect_item(item.id)) + } + fn visit_item(&mut self, i: &Item) { let orig_in_trait_impl = self.in_trait_impl; let orig_in_enum = self.in_enum; @@ -203,7 +210,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> { } self.annotate(i.id, &i.attrs, i.span, kind, |v| { - visit::walk_item(v, i) + intravisit::walk_item(v, i) }); self.in_trait_impl = orig_in_trait_impl; self.in_enum = orig_in_enum; @@ -211,7 +218,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> { fn visit_trait_item(&mut self, ti: &hir::TraitItem) { self.annotate(ti.id, &ti.attrs, ti.span, AnnotationKind::Required, |v| { - visit::walk_trait_item(v, ti); + intravisit::walk_trait_item(v, ti); }); } @@ -222,13 +229,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> { AnnotationKind::Required }; self.annotate(ii.id, &ii.attrs, ii.span, kind, |v| { - visit::walk_impl_item(v, ii); + intravisit::walk_impl_item(v, ii); }); } fn visit_variant(&mut self, var: &Variant, g: &'v Generics, item_id: NodeId) { self.annotate(var.node.data.id(), &var.node.attrs, var.span, AnnotationKind::Required, |v| { - visit::walk_variant(v, var, g, item_id); + intravisit::walk_variant(v, var, g, item_id); }) } @@ -240,13 +247,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> { AnnotationKind::Required }; self.annotate(s.node.id, &s.node.attrs, s.span, kind, |v| { - visit::walk_struct_field(v, s); + intravisit::walk_struct_field(v, s); }); } fn visit_foreign_item(&mut self, i: &hir::ForeignItem) { self.annotate(i.id, &i.attrs, i.span, AnnotationKind::Required, |v| { - visit::walk_foreign_item(v, i); + intravisit::walk_foreign_item(v, i); }); } @@ -259,7 +266,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> { impl<'tcx> Index<'tcx> { /// Construct the stability index for a crate being compiled. - pub fn build(&mut self, tcx: &ty::ctxt<'tcx>, krate: &Crate, export_map: &PublicItems) { + pub fn build(&mut self, tcx: &ty::ctxt<'tcx>, krate: &'tcx Crate, export_map: &PublicItems) { let mut annotator = Annotator { tcx: tcx, index: self, @@ -269,7 +276,7 @@ impl<'tcx> Index<'tcx> { in_enum: false, }; annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, krate.span, AnnotationKind::Required, - |v| visit::walk_crate(v, krate)); + |v| intravisit::walk_crate(v, krate)); } pub fn new(krate: &Crate) -> Index { @@ -308,9 +315,7 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt) used_features: FnvHashMap(), in_skip_block: 0, }; - - let krate = tcx.map.krate(); - visit::walk_crate(&mut checker, krate); + intravisit::walk_crate(&mut checker, tcx.map.krate()); let used_features = checker.used_features; return used_features; @@ -379,6 +384,13 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { } impl<'a, 'v, 'tcx> Visitor<'v> 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 visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.tcx.map.expect_item(item.id)) + } + fn visit_item(&mut self, item: &hir::Item) { // When compiling with --test we don't enforce stability on the // compiler-generated test module, demarcated with `DUMMY_SP` plus the @@ -387,31 +399,31 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> { check_item(self.tcx, item, true, &mut |id, sp, stab| self.check(id, sp, stab)); - visit::walk_item(self, item); + intravisit::walk_item(self, item); } fn visit_expr(&mut self, ex: &hir::Expr) { check_expr(self.tcx, ex, &mut |id, sp, stab| self.check(id, sp, stab)); - visit::walk_expr(self, ex); + intravisit::walk_expr(self, ex); } fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) { check_path(self.tcx, path, id, &mut |id, sp, stab| self.check(id, sp, stab)); - visit::walk_path(self, path) + intravisit::walk_path(self, path) } fn visit_path_list_item(&mut self, prefix: &hir::Path, item: &hir::PathListItem) { check_path_list_item(self.tcx, item, &mut |id, sp, stab| self.check(id, sp, stab)); - visit::walk_path_list_item(self, prefix, item) + intravisit::walk_path_list_item(self, prefix, item) } fn visit_pat(&mut self, pat: &hir::Pat) { check_pat(self.tcx, pat, &mut |id, sp, stab| self.check(id, sp, stab)); - visit::walk_pat(self, pat) + intravisit::walk_pat(self, pat) } fn visit_block(&mut self, b: &hir::Block) { @@ -425,7 +437,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> { } _ => {} } - visit::walk_block(self, b); + intravisit::walk_block(self, b); self.in_skip_block = old_skip_count; } } diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 96c8e5c7d5218..ee999c91097e7 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -18,8 +18,8 @@ use middle::lang_items; use syntax::ast; use syntax::codemap::Span; use syntax::parse::token::InternedString; -use rustc_front::visit::Visitor; -use rustc_front::visit; +use rustc_front::intravisit::Visitor; +use rustc_front::intravisit; use rustc_front::hir; use std::collections::HashSet; @@ -50,7 +50,7 @@ pub fn check_crate(krate: &hir::Crate, { let mut cx = Context { sess: sess, items: items }; - visit::walk_crate(&mut cx, krate); + krate.visit_all_items(&mut cx); } verify(sess, items); } @@ -114,7 +114,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { None => {} Some(lang_item) => self.register(&lang_item, i.span), } - visit::walk_foreign_item(self, i) + intravisit::walk_foreign_item(self, i) } } diff --git a/src/librustc/plugin/build.rs b/src/librustc/plugin/build.rs index ea85b264261cd..00f58c6af9155 100644 --- a/src/librustc/plugin/build.rs +++ b/src/librustc/plugin/build.rs @@ -14,8 +14,7 @@ use syntax::ast; use syntax::attr; use syntax::codemap::Span; use syntax::diagnostic; -use rustc_front::visit; -use rustc_front::visit::Visitor; +use rustc_front::intravisit::Visitor; use rustc_front::hir; struct RegistrarFinder { @@ -30,8 +29,6 @@ impl<'v> Visitor<'v> for RegistrarFinder { self.registrars.push((item.id, item.span)); } } - - visit::walk_item(self, item); } } @@ -40,7 +37,7 @@ pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler, krate: &hir::Crate) -> Option { let mut finder = RegistrarFinder { registrars: Vec::new() }; - visit::walk_crate(&mut finder, krate); + krate.visit_all_items(&mut finder); match finder.registrars.len() { 0 => None, diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 74b92318f2774..c6f58ef28802b 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -21,8 +21,8 @@ use std::path::Path; use std::time::Duration; use rustc_front::hir; -use rustc_front::visit; -use rustc_front::visit::Visitor; +use rustc_front::intravisit; +use rustc_front::intravisit::Visitor; // The name of the associated type for `Fn` return types pub const FN_OUTPUT_NAME: &'static str = "Output"; @@ -169,7 +169,7 @@ impl<'v, P> Visitor<'v> for LoopQueryVisitor

where P: FnMut(&hir::Expr_) -> b // Skip inner loops, since a break in the inner loop isn't a // break inside the outer loop hir::ExprLoop(..) | hir::ExprWhile(..) => {} - _ => visit::walk_expr(self, e) + _ => intravisit::walk_expr(self, e) } } } @@ -181,7 +181,7 @@ pub fn loop_query

(b: &hir::Block, p: P) -> bool where P: FnMut(&hir::Expr_) - p: p, flag: false, }; - visit::walk_block(&mut v, b); + intravisit::walk_block(&mut v, b); return v.flag; } @@ -193,7 +193,7 @@ struct BlockQueryVisitor

where P: FnMut(&hir::Expr) -> bool { impl<'v, P> Visitor<'v> for BlockQueryVisitor

where P: FnMut(&hir::Expr) -> bool { fn visit_expr(&mut self, e: &hir::Expr) { self.flag |= (self.p)(e); - visit::walk_expr(self, e) + intravisit::walk_expr(self, e) } } @@ -204,7 +204,7 @@ pub fn block_query

(b: &hir::Block, p: P) -> bool where P: FnMut(&hir::Expr) - p: p, flag: false, }; - visit::walk_block(&mut v, &*b); + intravisit::walk_block(&mut v, &*b); return v.flag; } diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index a9cfc7138d8d9..a5df0b94b3374 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -49,7 +49,7 @@ use std::fmt; use std::hash::{Hash, SipHasher, Hasher}; use rustc_front::hir; -use rustc_front::visit; +use rustc_front::intravisit as visit; #[derive(Clone, PartialEq, Debug)] pub struct Svh { @@ -83,7 +83,7 @@ impl Svh { } { - let mut visit = svh_visitor::make(&mut state); + let mut visit = svh_visitor::make(&mut state, krate); visit::walk_crate(&mut visit, krate); } @@ -134,19 +134,20 @@ mod svh_visitor { use syntax::ast::{self, Name, NodeId}; use syntax::codemap::Span; use syntax::parse::token; - use rustc_front::visit; - use rustc_front::visit::{Visitor, FnKind}; + use rustc_front::intravisit as visit; + use rustc_front::intravisit::{Visitor, FnKind}; use rustc_front::hir::*; use rustc_front::hir; use std::hash::{Hash, SipHasher}; pub struct StrictVersionHashVisitor<'a> { + pub krate: &'a Crate, pub st: &'a mut SipHasher, } - pub fn make<'a>(st: &'a mut SipHasher) -> StrictVersionHashVisitor<'a> { - StrictVersionHashVisitor { st: st } + pub fn make<'a>(st: &'a mut SipHasher, krate: &'a Crate) -> StrictVersionHashVisitor<'a> { + StrictVersionHashVisitor { st: st, krate: krate } } // To off-load the bulk of the hash-computation on #[derive(Hash)], @@ -300,15 +301,19 @@ mod svh_visitor { } } - impl<'a, 'v> Visitor<'v> for StrictVersionHashVisitor<'a> { - fn visit_variant_data(&mut self, s: &VariantData, name: Name, - g: &Generics, _: NodeId, _: Span) { + impl<'a> Visitor<'a> for StrictVersionHashVisitor<'a> { + fn visit_nested_item(&mut self, item: ItemId) { + self.visit_item(self.krate.item(item.id)) + } + + fn visit_variant_data(&mut self, s: &'a VariantData, name: Name, + g: &'a Generics, _: NodeId, _: Span) { SawStructDef(name.as_str()).hash(self.st); visit::walk_generics(self, g); visit::walk_struct_def(self, s) } - fn visit_variant(&mut self, v: &Variant, g: &Generics, item_id: NodeId) { + fn visit_variant(&mut self, v: &'a Variant, g: &'a Generics, item_id: NodeId) { SawVariant.hash(self.st); // walk_variant does not call walk_generics, so do it here. visit::walk_generics(self, g); @@ -333,11 +338,11 @@ mod svh_visitor { SawIdent(name.as_str()).hash(self.st); } - fn visit_lifetime(&mut self, l: &Lifetime) { + fn visit_lifetime(&mut self, l: &'a Lifetime) { SawLifetime(l.name.as_str()).hash(self.st); } - fn visit_lifetime_def(&mut self, l: &LifetimeDef) { + fn visit_lifetime_def(&mut self, l: &'a LifetimeDef) { SawLifetimeDef(l.lifetime.name.as_str()).hash(self.st); } @@ -346,15 +351,15 @@ mod svh_visitor { // monomorphization and cross-crate inlining generally implies // that a change to a crate body will require downstream // crates to be recompiled. - fn visit_expr(&mut self, ex: &Expr) { + fn visit_expr(&mut self, ex: &'a Expr) { SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex) } - fn visit_stmt(&mut self, s: &Stmt) { + fn visit_stmt(&mut self, s: &'a Stmt) { SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s) } - fn visit_foreign_item(&mut self, i: &ForeignItem) { + fn visit_foreign_item(&mut self, i: &'a ForeignItem) { // FIXME (#14132) ideally we would incorporate privacy (or // perhaps reachability) somewhere here, so foreign items // that do not leak into downstream crates would not be @@ -362,7 +367,7 @@ mod svh_visitor { SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i) } - fn visit_item(&mut self, i: &Item) { + fn visit_item(&mut self, i: &'a Item) { // FIXME (#14132) ideally would incorporate reachability // analysis somewhere here, so items that never leak into // downstream crates (e.g. via monomorphisation or @@ -370,64 +375,64 @@ mod svh_visitor { SawItem.hash(self.st); visit::walk_item(self, i) } - fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId) { + fn visit_mod(&mut self, m: &'a Mod, _s: Span, _n: NodeId) { SawMod.hash(self.st); visit::walk_mod(self, m) } - fn visit_decl(&mut self, d: &Decl) { + fn visit_decl(&mut self, d: &'a Decl) { SawDecl.hash(self.st); visit::walk_decl(self, d) } - fn visit_ty(&mut self, t: &Ty) { + fn visit_ty(&mut self, t: &'a Ty) { SawTy.hash(self.st); visit::walk_ty(self, t) } - fn visit_generics(&mut self, g: &Generics) { + fn visit_generics(&mut self, g: &'a Generics) { SawGenerics.hash(self.st); visit::walk_generics(self, g) } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, - b: &'v Block, s: Span, _: NodeId) { + fn visit_fn(&mut self, fk: FnKind<'a>, fd: &'a FnDecl, + b: &'a Block, s: Span, _: NodeId) { SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s) } - fn visit_trait_item(&mut self, ti: &TraitItem) { + fn visit_trait_item(&mut self, ti: &'a TraitItem) { SawTraitItem.hash(self.st); visit::walk_trait_item(self, ti) } - fn visit_impl_item(&mut self, ii: &ImplItem) { + fn visit_impl_item(&mut self, ii: &'a ImplItem) { SawImplItem.hash(self.st); visit::walk_impl_item(self, ii) } - fn visit_struct_field(&mut self, s: &StructField) { + fn visit_struct_field(&mut self, s: &'a StructField) { SawStructField.hash(self.st); visit::walk_struct_field(self, s) } - fn visit_explicit_self(&mut self, es: &ExplicitSelf) { + fn visit_explicit_self(&mut self, es: &'a ExplicitSelf) { SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es) } - fn visit_path(&mut self, path: &Path, _: ast::NodeId) { + fn visit_path(&mut self, path: &'a Path, _: ast::NodeId) { SawPath.hash(self.st); visit::walk_path(self, path) } - fn visit_path_list_item(&mut self, prefix: &Path, item: &'v PathListItem) { + fn visit_path_list_item(&mut self, prefix: &'a Path, item: &'a PathListItem) { SawPath.hash(self.st); visit::walk_path_list_item(self, prefix, item) } - fn visit_block(&mut self, b: &Block) { + fn visit_block(&mut self, b: &'a Block) { SawBlock.hash(self.st); visit::walk_block(self, b) } - fn visit_pat(&mut self, p: &Pat) { + fn visit_pat(&mut self, p: &'a Pat) { SawPat.hash(self.st); visit::walk_pat(self, p) } - fn visit_local(&mut self, l: &Local) { + fn visit_local(&mut self, l: &'a Local) { SawLocal.hash(self.st); visit::walk_local(self, l) } - fn visit_arm(&mut self, a: &Arm) { + fn visit_arm(&mut self, a: &'a Arm) { SawArm.hash(self.st); visit::walk_arm(self, a) } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index de0b1fddc2006..083cc972ccad2 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -30,8 +30,8 @@ use syntax::codemap::Span; use syntax::ast::NodeId; use rustc_front::hir; use rustc_front::hir::{Expr, FnDecl, Block, Pat}; -use rustc_front::visit; -use rustc_front::visit::Visitor; +use rustc_front::intravisit; +use rustc_front::intravisit::Visitor; mod lifetime; mod restrictions; @@ -533,7 +533,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> { } } - visit::walk_expr(self, ex); + intravisit::walk_expr(self, ex); } } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index f1eff5f55f29c..a9a7b34df12c4 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -43,8 +43,8 @@ use syntax::codemap::Span; use rustc_front::hir; use rustc_front::hir::{FnDecl, Block}; -use rustc_front::visit; -use rustc_front::visit::{Visitor, FnKind}; +use rustc_front::intravisit; +use rustc_front::intravisit::{Visitor, FnKind}; use rustc_front::util as hir_util; pub mod check_loans; @@ -85,14 +85,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> { if let hir::ConstTraitItem(_, Some(ref expr)) = ti.node { gather_loans::gather_loans_in_static_initializer(self, &*expr); } - visit::walk_trait_item(self, ti); + intravisit::walk_trait_item(self, ti); } fn visit_impl_item(&mut self, ii: &hir::ImplItem) { if let hir::ImplItemKind::Const(_, ref expr) = ii.node { gather_loans::gather_loans_in_static_initializer(self, &*expr); } - visit::walk_impl_item(self, ii); + intravisit::walk_impl_item(self, ii); } } @@ -108,7 +108,7 @@ pub fn check_crate(tcx: &ty::ctxt) { } }; - visit::walk_crate(&mut bccx, tcx.map.krate()); + tcx.map.krate().visit_all_items(&mut bccx); if tcx.sess.borrowck_stats() { println!("--- borrowck stats ---"); @@ -142,7 +142,7 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &hir::Item) { _ => { } } - visit::walk_item(this, item); + intravisit::walk_item(this, item); } /// Collection of conclusions determined via borrow checker analyses. @@ -181,7 +181,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt, decl, body); - visit::walk_fn(this, fk, decl, body, sp); + intravisit::walk_fn(this, fk, decl, body, sp); } fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 5db3ee59cae4f..f8ac2759e854d 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -827,7 +827,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, time(time_passes, "lint checking", - || lint::check_crate(tcx, krate, &exported_items)); + || lint::check_crate(tcx, &exported_items)); // The above three passes generate errors w/o aborting tcx.sess.abort_if_errors(); diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 04f7938e9ba4f..8815d57472552 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -777,7 +777,8 @@ pub fn pretty_print_input(sess: Session, &mut rdr, box out, annotation.pp_ann(), - true); + true, + Some(ast_map.krate())); for node_id in uii.all_matching_node_ids(ast_map) { let node = ast_map.get(node_id); try!(pp_state.print_node(&node)); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index fe9cf7cc3875f..e33f5df4d3da4 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -189,9 +189,10 @@ impl<'a, 'tcx> Env<'a, 'tcx> { names: &[String]) -> Option { assert!(idx < names.len()); - for item in &m.items { + for item in &m.item_ids { + let item = this.infcx.tcx.map.expect_item(item.id); if item.name.to_string() == names[idx] { - return search(this, &**item, idx + 1, names); + return search(this, item, idx + 1, names); } } return None; diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs index b963aba9c07eb..7ec4e1ba33121 100644 --- a/src/librustc_front/fold.rs +++ b/src/librustc_front/fold.rs @@ -77,10 +77,14 @@ pub trait Folder : Sized { noop_fold_foreign_item(ni, self) } - fn fold_item(&mut self, i: P) -> P { + fn fold_item(&mut self, i: Item) -> Item { noop_fold_item(i, self) } + fn fold_item_id(&mut self, i: ItemId) -> ItemId { + noop_fold_item_id(i, self) + } + fn fold_struct_field(&mut self, sf: StructField) -> StructField { noop_fold_struct_field(sf, self) } @@ -271,10 +275,16 @@ pub trait Folder : Sized { noop_fold_where_predicate(where_predicate, self) } + /// called for the `id` on each declaration fn new_id(&mut self, i: NodeId) -> NodeId { i } + /// called for ids that are references (e.g., ItemDef) + fn map_id(&mut self, i: NodeId) -> NodeId { + i + } + fn new_span(&mut self, sp: Span) -> Span { sp } @@ -342,7 +352,7 @@ pub fn noop_fold_decl(d: P, fld: &mut T) -> P { span: fld.new_span(span), }, DeclItem(it) => Spanned { - node: DeclItem(fld.fold_item(it)), + node: DeclItem(fld.fold_item_id(it)), span: fld.new_span(span), }, } @@ -879,34 +889,40 @@ pub fn noop_fold_impl_item(i: P, folder: &mut T) -> P(Mod { inner, items }: Mod, folder: &mut T) -> Mod { +pub fn noop_fold_mod(Mod { inner, item_ids }: Mod, folder: &mut T) -> Mod { Mod { inner: folder.new_span(inner), - items: items.into_iter().map(|x| folder.fold_item(x)).collect(), + item_ids: item_ids.into_iter().map(|x| folder.fold_item_id(x)).collect(), } } -pub fn noop_fold_crate(Crate { module, attrs, config, span, exported_macros }: Crate, +pub fn noop_fold_crate(Crate { module, attrs, config, span, + exported_macros, items }: Crate, folder: &mut T) -> Crate { let config = folder.fold_meta_items(config); - let crate_mod = folder.fold_item(P(hir::Item { + let crate_mod = folder.fold_item(hir::Item { name: token::special_idents::invalid.name, attrs: attrs, id: DUMMY_NODE_ID, vis: hir::Public, span: span, node: hir::ItemMod(module), - })); + }); - let (module, attrs, span) = - crate_mod.and_then(|hir::Item { attrs, span, node, .. }| { + let (module, attrs, span) = match crate_mod { + hir::Item { attrs, span, node, .. } => { match node { hir::ItemMod(m) => (m, attrs, span), _ => panic!("fold converted a module to not a module"), } - }); + } + }; + + let items = items.into_iter() + .map(|(id, item)| (id, folder.fold_item(item))) + .collect(); Crate { module: module, @@ -914,31 +930,37 @@ pub fn noop_fold_crate(Crate { module, attrs, config, span, exported_ config: config, span: span, exported_macros: exported_macros, + items: items, } } -pub fn noop_fold_item(item: P, folder: &mut T) -> P { - item.map(|Item { id, name, attrs, node, vis, span }| { - let id = folder.new_id(id); - let node = folder.fold_item_underscore(node); - // FIXME: we should update the impl_pretty_name, but it uses pretty printing. - // let ident = match node { - // // The node may have changed, recompute the "pretty" impl name. - // ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => { - // impl_pretty_name(maybe_trait, Some(&**ty)) - // } - // _ => ident - // }; - - Item { - id: id, - name: folder.fold_name(name), - attrs: fold_attrs(attrs, folder), - node: node, - vis: vis, - span: folder.new_span(span), - } - }) +pub fn noop_fold_item_id(i: ItemId, folder: &mut T) -> ItemId { + let id = folder.map_id(i.id); + ItemId { id: id } +} + +// fold one item into one item +pub fn noop_fold_item(item: Item, folder: &mut T) -> Item { + let Item { id, name, attrs, node, vis, span } = item; + let id = folder.new_id(id); + let node = folder.fold_item_underscore(node); + // FIXME: we should update the impl_pretty_name, but it uses pretty printing. + // let ident = match node { + // // The node may have changed, recompute the "pretty" impl name. + // ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => { + // impl_pretty_name(maybe_trait, Some(&**ty)) + // } + // _ => ident + // }; + + Item { + id: id, + name: folder.fold_name(name), + attrs: fold_attrs(attrs, folder), + node: node, + vis: vis, + span: folder.new_span(span), + } } pub fn noop_fold_foreign_item(ni: P, folder: &mut T) -> P { diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs index 1fa7c9d301c0d..95d73daa632b1 100644 --- a/src/librustc_front/hir.rs +++ b/src/librustc_front/hir.rs @@ -35,6 +35,8 @@ pub use self::ViewPath_::*; pub use self::Visibility::*; pub use self::PathParameters::*; +use intravisit::Visitor; +use std::collections::BTreeMap; use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId}; use syntax::abi::Abi; use syntax::ast::{Name, Ident, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect}; @@ -320,13 +322,41 @@ pub struct WhereEqPredicate { pub ty: P, } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] pub struct Crate { pub module: Mod, pub attrs: Vec, pub config: CrateConfig, pub span: Span, pub exported_macros: Vec, + + // NB: We use a BTreeMap here so that `visit_all_items` iterates + // over the ids in increasing order. In principle it should not + // matter what order we visit things in, but in *practice* it + // does, because it can affect the order in which errors are + // detected, which in turn can make compile-fail tests yield + // slightly different results. + pub items: BTreeMap, +} + +impl Crate { + pub fn item(&self, id: NodeId) -> &Item { + &self.items[&id] + } + + /// Visits all items in the crate in some determinstic (but + /// unspecified) order. If you just need to process every item, + /// but don't care about nesting, this method is the best choice. + /// + /// If you do care about nesting -- usually because your algorithm + /// follows lexical scoping rules -- then you want a different + /// approach. You should override `visit_nested_item` in your + /// visitor and then call `intravisit::walk_crate` instead. + pub fn visit_all_items<'hir, V:Visitor<'hir>>(&'hir self, visitor: &mut V) { + for (_, item) in &self.items { + visitor.visit_item(item); + } + } } /// A macro definition, in this crate or imported from another. @@ -537,7 +567,7 @@ pub enum Decl_ { /// A local (let) binding: DeclLocal(P), /// An item binding: - DeclItem(P), + DeclItem(ItemId), } /// represents one arm of a 'match' @@ -992,7 +1022,7 @@ pub struct Mod { /// For `mod foo;`, the inner span ranges from the first token /// to the last token in the external file. pub inner: Span, - pub items: Vec>, + pub item_ids: Vec, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -1205,7 +1235,13 @@ impl VariantData { } } - +// The bodies for items are stored "out of line", in a separate +// hashmap in the `Crate`. Here we just record the node-id of the item +// so it can fetched later. +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ItemId { + pub id: NodeId, +} // FIXME (#3300): Should allow items to be anonymous. Right now // we just use dummy names for anon items. diff --git a/src/librustc_front/visit.rs b/src/librustc_front/intravisit.rs similarity index 93% rename from src/librustc_front/visit.rs rename to src/librustc_front/intravisit.rs index ec58f31b6decd..3a43feb8ba74b 100644 --- a/src/librustc_front/visit.rs +++ b/src/librustc_front/intravisit.rs @@ -13,15 +13,17 @@ //! call `visit::walk_*` to apply the default traversal algorithm, or prevent //! deeper traversal by doing nothing. //! -//! Note: it is an important invariant that the default visitor walks the body -//! of a function in "execution order" (more concretely, reverse post-order -//! with respect to the CFG implied by the AST), meaning that if AST node A may -//! execute before AST node B, then A is visited first. The borrow checker in -//! particular relies on this property. +//! When visiting the HIR, the contents of nested items are NOT visited +//! by default. This is different from the AST visitor, which does a deep walk. +//! Hence this module is called `intravisit`; see the method `visit_nested_item` +//! for more details. //! -//! Note: walking an AST before macro expansion is probably a bad idea. For -//! instance, a walker looking for item names in a module will miss all of -//! those that are created by the expansion of a macro. +//! Note: it is an important invariant that the default visitor walks +//! the body of a function in "execution order" (more concretely, +//! reverse post-order with respect to the CFG implied by the AST), +//! meaning that if AST node A may execute before AST node B, then A +//! is visited first. The borrow checker in particular relies on this +//! property. use syntax::abi::Abi; use syntax::ast::{Ident, NodeId, CRATE_NODE_ID, Name, Attribute}; @@ -45,11 +47,39 @@ pub enum FnKind<'a> { /// the substructure of the input via the corresponding `walk` method; /// e.g. the `visit_mod` method by default calls `visit::walk_mod`. /// +/// Note that this visitor does NOT visit nested items by default +/// (this is why the module is called `intravisit`, to distinguish it +/// from the AST's `visit` module, which acts differently). If you +/// simply want to visit all items in the crate in some order, you +/// should call `Crate::visit_all_items`. Otherwise, see the comment +/// on `visit_nested_item` for details on how to visit nested items. +/// /// If you want to ensure that your code handles every variant /// explicitly, you need to override each method. (And you also need /// to monitor future changes to `Visitor` in case a new method with a /// new default implementation gets introduced.) pub trait Visitor<'v> : Sized { + /////////////////////////////////////////////////////////////////////////// + // Nested items. + + /// Invoked when a nested item is encountered. By default, does + /// nothing. If you want a deep walk, you need to override to + /// fetch the item contents. But most of the time, it is easier + /// (and better) to invoke `Crate::visit_all_items`, which visits + /// all items in the crate in some order (but doesn't respect + /// nesting). + #[allow(unused_variables)] + fn visit_nested_item(&mut self, id: ItemId) { + } + + /// Visit the top-level item and (optionally) nested items. See + /// `visit_nested_item` for details. + fn visit_item(&mut self, i: &'v Item) { + walk_item(self, i) + } + + /////////////////////////////////////////////////////////////////////////// + fn visit_name(&mut self, _span: Span, _name: Name) { // Nothing to do. } @@ -62,9 +92,6 @@ pub trait Visitor<'v> : Sized { fn visit_foreign_item(&mut self, i: &'v ForeignItem) { walk_foreign_item(self, i) } - fn visit_item(&mut self, i: &'v Item) { - walk_item(self, i) - } fn visit_local(&mut self, l: &'v Local) { walk_local(self, l) } @@ -180,6 +207,7 @@ pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, ident: Ident) visitor.visit_name(span, ident.name); } +/// Walks the contents of a crate. See also `Crate::visit_all_items`. pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) { visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID); walk_list!(visitor, visit_attribute, &krate.attrs); @@ -193,7 +221,9 @@ pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroD } pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) { - walk_list!(visitor, visit_item, &module.items); + for &item_id in &module.item_ids { + visitor.visit_nested_item(item_id); + } } pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { @@ -658,7 +688,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) { match declaration.node { DeclLocal(ref local) => visitor.visit_local(local), - DeclItem(ref item) => visitor.visit_item(item), + DeclItem(item) => visitor.visit_nested_item(item), } } diff --git a/src/librustc_front/lib.rs b/src/librustc_front/lib.rs index 022744cbc3a14..bafda3086fd89 100644 --- a/src/librustc_front/lib.rs +++ b/src/librustc_front/lib.rs @@ -51,7 +51,7 @@ extern crate serialize as rustc_serialize; // used by deriving pub mod hir; pub mod lowering; pub mod fold; -pub mod visit; +pub mod intravisit; pub mod util; pub mod print { diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs index 8ef49d185f727..b984f23c4c02a 100644 --- a/src/librustc_front/lowering.rs +++ b/src/librustc_front/lowering.rs @@ -63,14 +63,15 @@ use hir; +use std::collections::BTreeMap; use std::collections::HashMap; - use syntax::ast::*; use syntax::ptr::P; use syntax::codemap::{respan, Spanned, Span}; use syntax::owned_slice::OwnedSlice; use syntax::parse::token::{self, str_to_ident}; use syntax::std_inject; +use syntax::visit::{self, Visitor}; use std::cell::{Cell, RefCell}; @@ -138,17 +139,17 @@ impl<'a, 'hir> LoweringContext<'a> { } } -pub fn lower_view_path(_lctx: &LoweringContext, view_path: &ViewPath) -> P { +pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P { P(Spanned { node: match view_path.node { ViewPathSimple(ident, ref path) => { - hir::ViewPathSimple(ident.name, lower_path(_lctx, path)) + hir::ViewPathSimple(ident.name, lower_path(lctx, path)) } ViewPathGlob(ref path) => { - hir::ViewPathGlob(lower_path(_lctx, path)) + hir::ViewPathGlob(lower_path(lctx, path)) } ViewPathList(ref path, ref path_list_idents) => { - hir::ViewPathList(lower_path(_lctx, path), + hir::ViewPathList(lower_path(lctx, path), path_list_idents.iter() .map(|path_list_ident| { Spanned { @@ -175,79 +176,79 @@ pub fn lower_view_path(_lctx: &LoweringContext, view_path: &ViewPath) -> P hir::Arm { +pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm { hir::Arm { attrs: arm.attrs.clone(), - pats: arm.pats.iter().map(|x| lower_pat(_lctx, x)).collect(), - guard: arm.guard.as_ref().map(|ref x| lower_expr(_lctx, x)), - body: lower_expr(_lctx, &arm.body), + pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(), + guard: arm.guard.as_ref().map(|ref x| lower_expr(lctx, x)), + body: lower_expr(lctx, &arm.body), } } -pub fn lower_decl(_lctx: &LoweringContext, d: &Decl) -> P { +pub fn lower_decl(lctx: &LoweringContext, d: &Decl) -> P { match d.node { DeclLocal(ref l) => P(Spanned { - node: hir::DeclLocal(lower_local(_lctx, l)), + node: hir::DeclLocal(lower_local(lctx, l)), span: d.span, }), DeclItem(ref it) => P(Spanned { - node: hir::DeclItem(lower_item(_lctx, it)), + node: hir::DeclItem(lower_item_id(lctx, it)), span: d.span, }), } } -pub fn lower_ty_binding(_lctx: &LoweringContext, b: &TypeBinding) -> P { +pub fn lower_ty_binding(lctx: &LoweringContext, b: &TypeBinding) -> P { P(hir::TypeBinding { id: b.id, name: b.ident.name, - ty: lower_ty(_lctx, &b.ty), + ty: lower_ty(lctx, &b.ty), span: b.span, }) } -pub fn lower_ty(_lctx: &LoweringContext, t: &Ty) -> P { +pub fn lower_ty(lctx: &LoweringContext, t: &Ty) -> P { P(hir::Ty { id: t.id, node: match t.node { TyInfer => hir::TyInfer, - TyVec(ref ty) => hir::TyVec(lower_ty(_lctx, ty)), - TyPtr(ref mt) => hir::TyPtr(lower_mt(_lctx, mt)), + TyVec(ref ty) => hir::TyVec(lower_ty(lctx, ty)), + TyPtr(ref mt) => hir::TyPtr(lower_mt(lctx, mt)), TyRptr(ref region, ref mt) => { - hir::TyRptr(lower_opt_lifetime(_lctx, region), lower_mt(_lctx, mt)) + hir::TyRptr(lower_opt_lifetime(lctx, region), lower_mt(lctx, mt)) } TyBareFn(ref f) => { hir::TyBareFn(P(hir::BareFnTy { - lifetimes: lower_lifetime_defs(_lctx, &f.lifetimes), - unsafety: lower_unsafety(_lctx, f.unsafety), + lifetimes: lower_lifetime_defs(lctx, &f.lifetimes), + unsafety: lower_unsafety(lctx, f.unsafety), abi: f.abi, - decl: lower_fn_decl(_lctx, &f.decl), + decl: lower_fn_decl(lctx, &f.decl), })) } - TyTup(ref tys) => hir::TyTup(tys.iter().map(|ty| lower_ty(_lctx, ty)).collect()), + TyTup(ref tys) => hir::TyTup(tys.iter().map(|ty| lower_ty(lctx, ty)).collect()), TyParen(ref ty) => { - return lower_ty(_lctx, ty); + return lower_ty(lctx, ty); } TyPath(ref qself, ref path) => { let qself = qself.as_ref().map(|&QSelf { ref ty, position }| { hir::QSelf { - ty: lower_ty(_lctx, ty), + ty: lower_ty(lctx, ty), position: position, } }); - hir::TyPath(qself, lower_path(_lctx, path)) + hir::TyPath(qself, lower_path(lctx, path)) } TyObjectSum(ref ty, ref bounds) => { - hir::TyObjectSum(lower_ty(_lctx, ty), lower_bounds(_lctx, bounds)) + hir::TyObjectSum(lower_ty(lctx, ty), lower_bounds(lctx, bounds)) } TyFixedLengthVec(ref ty, ref e) => { - hir::TyFixedLengthVec(lower_ty(_lctx, ty), lower_expr(_lctx, e)) + hir::TyFixedLengthVec(lower_ty(lctx, ty), lower_expr(lctx, e)) } TyTypeof(ref expr) => { - hir::TyTypeof(lower_expr(_lctx, expr)) + hir::TyTypeof(lower_expr(lctx, expr)) } TyPolyTraitRef(ref bounds) => { - hir::TyPolyTraitRef(bounds.iter().map(|b| lower_ty_param_bound(_lctx, b)).collect()) + hir::TyPolyTraitRef(bounds.iter().map(|b| lower_ty_param_bound(lctx, b)).collect()) } TyMac(_) => panic!("TyMac should have been expanded by now."), }, @@ -255,26 +256,26 @@ pub fn lower_ty(_lctx: &LoweringContext, t: &Ty) -> P { }) } -pub fn lower_foreign_mod(_lctx: &LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { +pub fn lower_foreign_mod(lctx: &LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { hir::ForeignMod { abi: fm.abi, - items: fm.items.iter().map(|x| lower_foreign_item(_lctx, x)).collect(), + items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(), } } -pub fn lower_variant(_lctx: &LoweringContext, v: &Variant) -> P { +pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> P { P(Spanned { node: hir::Variant_ { name: v.node.name.name, attrs: v.node.attrs.clone(), - data: lower_variant_data(_lctx, &v.node.data), - disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(_lctx, e)), + data: lower_variant_data(lctx, &v.node.data), + disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(lctx, e)), }, span: v.span, }) } -pub fn lower_path(_lctx: &LoweringContext, p: &Path) -> hir::Path { +pub fn lower_path(lctx: &LoweringContext, p: &Path) -> hir::Path { hir::Path { global: p.global, segments: p.segments @@ -282,7 +283,7 @@ pub fn lower_path(_lctx: &LoweringContext, p: &Path) -> hir::Path { .map(|&PathSegment { identifier, ref parameters }| { hir::PathSegment { identifier: identifier, - parameters: lower_path_parameters(_lctx, parameters), + parameters: lower_path_parameters(lctx, parameters), } }) .collect(), @@ -290,62 +291,62 @@ pub fn lower_path(_lctx: &LoweringContext, p: &Path) -> hir::Path { } } -pub fn lower_path_parameters(_lctx: &LoweringContext, +pub fn lower_path_parameters(lctx: &LoweringContext, path_parameters: &PathParameters) -> hir::PathParameters { match *path_parameters { AngleBracketedParameters(ref data) => - hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(_lctx, data)), + hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)), ParenthesizedParameters(ref data) => - hir::ParenthesizedParameters(lower_parenthesized_parameter_data(_lctx, data)), + hir::ParenthesizedParameters(lower_parenthesized_parameter_data(lctx, data)), } } -pub fn lower_angle_bracketed_parameter_data(_lctx: &LoweringContext, +pub fn lower_angle_bracketed_parameter_data(lctx: &LoweringContext, data: &AngleBracketedParameterData) -> hir::AngleBracketedParameterData { let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; hir::AngleBracketedParameterData { - lifetimes: lower_lifetimes(_lctx, lifetimes), - types: types.iter().map(|ty| lower_ty(_lctx, ty)).collect(), - bindings: bindings.iter().map(|b| lower_ty_binding(_lctx, b)).collect(), + lifetimes: lower_lifetimes(lctx, lifetimes), + types: types.iter().map(|ty| lower_ty(lctx, ty)).collect(), + bindings: bindings.iter().map(|b| lower_ty_binding(lctx, b)).collect(), } } -pub fn lower_parenthesized_parameter_data(_lctx: &LoweringContext, +pub fn lower_parenthesized_parameter_data(lctx: &LoweringContext, data: &ParenthesizedParameterData) -> hir::ParenthesizedParameterData { let &ParenthesizedParameterData { ref inputs, ref output, span } = data; hir::ParenthesizedParameterData { - inputs: inputs.iter().map(|ty| lower_ty(_lctx, ty)).collect(), - output: output.as_ref().map(|ty| lower_ty(_lctx, ty)), + inputs: inputs.iter().map(|ty| lower_ty(lctx, ty)).collect(), + output: output.as_ref().map(|ty| lower_ty(lctx, ty)), span: span, } } -pub fn lower_local(_lctx: &LoweringContext, l: &Local) -> P { +pub fn lower_local(lctx: &LoweringContext, l: &Local) -> P { P(hir::Local { id: l.id, - ty: l.ty.as_ref().map(|t| lower_ty(_lctx, t)), - pat: lower_pat(_lctx, &l.pat), - init: l.init.as_ref().map(|e| lower_expr(_lctx, e)), + ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)), + pat: lower_pat(lctx, &l.pat), + init: l.init.as_ref().map(|e| lower_expr(lctx, e)), span: l.span, }) } -pub fn lower_explicit_self_underscore(_lctx: &LoweringContext, +pub fn lower_explicit_self_underscore(lctx: &LoweringContext, es: &ExplicitSelf_) -> hir::ExplicitSelf_ { match *es { SelfStatic => hir::SelfStatic, SelfValue(v) => hir::SelfValue(v.name), SelfRegion(ref lifetime, m, ident) => { - hir::SelfRegion(lower_opt_lifetime(_lctx, lifetime), - lower_mutability(_lctx, m), + hir::SelfRegion(lower_opt_lifetime(lctx, lifetime), + lower_mutability(lctx, m), ident.name) } SelfExplicit(ref typ, ident) => { - hir::SelfExplicit(lower_ty(_lctx, typ), ident.name) + hir::SelfExplicit(lower_ty(lctx, typ), ident.name) } } } @@ -357,26 +358,26 @@ pub fn lower_mutability(_lctx: &LoweringContext, m: Mutability) -> hir::Mutabili } } -pub fn lower_explicit_self(_lctx: &LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { +pub fn lower_explicit_self(lctx: &LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { Spanned { - node: lower_explicit_self_underscore(_lctx, &s.node), + node: lower_explicit_self_underscore(lctx, &s.node), span: s.span, } } -pub fn lower_arg(_lctx: &LoweringContext, arg: &Arg) -> hir::Arg { +pub fn lower_arg(lctx: &LoweringContext, arg: &Arg) -> hir::Arg { hir::Arg { id: arg.id, - pat: lower_pat(_lctx, &arg.pat), - ty: lower_ty(_lctx, &arg.ty), + pat: lower_pat(lctx, &arg.pat), + ty: lower_ty(lctx, &arg.ty), } } -pub fn lower_fn_decl(_lctx: &LoweringContext, decl: &FnDecl) -> P { +pub fn lower_fn_decl(lctx: &LoweringContext, decl: &FnDecl) -> P { P(hir::FnDecl { - inputs: decl.inputs.iter().map(|x| lower_arg(_lctx, x)).collect(), + inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(), output: match decl.output { - Return(ref ty) => hir::Return(lower_ty(_lctx, ty)), + Return(ref ty) => hir::Return(lower_ty(lctx, ty)), DefaultReturn(span) => hir::DefaultReturn(span), NoReturn(span) => hir::NoReturn(span), }, @@ -384,32 +385,32 @@ pub fn lower_fn_decl(_lctx: &LoweringContext, decl: &FnDecl) -> P { }) } -pub fn lower_ty_param_bound(_lctx: &LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { +pub fn lower_ty_param_bound(lctx: &LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { match *tpb { TraitTyParamBound(ref ty, modifier) => { - hir::TraitTyParamBound(lower_poly_trait_ref(_lctx, ty), - lower_trait_bound_modifier(_lctx, modifier)) + hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty), + lower_trait_bound_modifier(lctx, modifier)) } RegionTyParamBound(ref lifetime) => { - hir::RegionTyParamBound(lower_lifetime(_lctx, lifetime)) + hir::RegionTyParamBound(lower_lifetime(lctx, lifetime)) } } } -pub fn lower_ty_param(_lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam { +pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam { hir::TyParam { id: tp.id, name: tp.ident.name, - bounds: lower_bounds(_lctx, &tp.bounds), - default: tp.default.as_ref().map(|x| lower_ty(_lctx, x)), + bounds: lower_bounds(lctx, &tp.bounds), + default: tp.default.as_ref().map(|x| lower_ty(lctx, x)), span: tp.span, } } -pub fn lower_ty_params(_lctx: &LoweringContext, +pub fn lower_ty_params(lctx: &LoweringContext, tps: &OwnedSlice) -> OwnedSlice { - tps.iter().map(|tp| lower_ty_param(_lctx, tp)).collect() + tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() } pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime { @@ -420,48 +421,48 @@ pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime { } } -pub fn lower_lifetime_def(_lctx: &LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { +pub fn lower_lifetime_def(lctx: &LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { hir::LifetimeDef { - lifetime: lower_lifetime(_lctx, &l.lifetime), - bounds: lower_lifetimes(_lctx, &l.bounds), + lifetime: lower_lifetime(lctx, &l.lifetime), + bounds: lower_lifetimes(lctx, &l.bounds), } } -pub fn lower_lifetimes(_lctx: &LoweringContext, lts: &Vec) -> Vec { - lts.iter().map(|l| lower_lifetime(_lctx, l)).collect() +pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec) -> Vec { + lts.iter().map(|l| lower_lifetime(lctx, l)).collect() } -pub fn lower_lifetime_defs(_lctx: &LoweringContext, +pub fn lower_lifetime_defs(lctx: &LoweringContext, lts: &Vec) -> Vec { - lts.iter().map(|l| lower_lifetime_def(_lctx, l)).collect() + lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect() } -pub fn lower_opt_lifetime(_lctx: &LoweringContext, +pub fn lower_opt_lifetime(lctx: &LoweringContext, o_lt: &Option) -> Option { - o_lt.as_ref().map(|lt| lower_lifetime(_lctx, lt)) + o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt)) } -pub fn lower_generics(_lctx: &LoweringContext, g: &Generics) -> hir::Generics { +pub fn lower_generics(lctx: &LoweringContext, g: &Generics) -> hir::Generics { hir::Generics { - ty_params: lower_ty_params(_lctx, &g.ty_params), - lifetimes: lower_lifetime_defs(_lctx, &g.lifetimes), - where_clause: lower_where_clause(_lctx, &g.where_clause), + ty_params: lower_ty_params(lctx, &g.ty_params), + lifetimes: lower_lifetime_defs(lctx, &g.lifetimes), + where_clause: lower_where_clause(lctx, &g.where_clause), } } -pub fn lower_where_clause(_lctx: &LoweringContext, wc: &WhereClause) -> hir::WhereClause { +pub fn lower_where_clause(lctx: &LoweringContext, wc: &WhereClause) -> hir::WhereClause { hir::WhereClause { id: wc.id, predicates: wc.predicates .iter() - .map(|predicate| lower_where_predicate(_lctx, predicate)) + .map(|predicate| lower_where_predicate(lctx, predicate)) .collect(), } } -pub fn lower_where_predicate(_lctx: &LoweringContext, +pub fn lower_where_predicate(lctx: &LoweringContext, pred: &WherePredicate) -> hir::WherePredicate { match *pred { @@ -470,9 +471,9 @@ pub fn lower_where_predicate(_lctx: &LoweringContext, ref bounds, span}) => { hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - bound_lifetimes: lower_lifetime_defs(_lctx, bound_lifetimes), - bounded_ty: lower_ty(_lctx, bounded_ty), - bounds: bounds.iter().map(|x| lower_ty_param_bound(_lctx, x)).collect(), + bound_lifetimes: lower_lifetime_defs(lctx, bound_lifetimes), + bounded_ty: lower_ty(lctx, bounded_ty), + bounds: bounds.iter().map(|x| lower_ty_param_bound(lctx, x)).collect(), span: span, }) } @@ -481,8 +482,8 @@ pub fn lower_where_predicate(_lctx: &LoweringContext, span}) => { hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { span: span, - lifetime: lower_lifetime(_lctx, lifetime), - bounds: bounds.iter().map(|bound| lower_lifetime(_lctx, bound)).collect(), + lifetime: lower_lifetime(lctx, lifetime), + bounds: bounds.iter().map(|bound| lower_lifetime(lctx, bound)).collect(), }) } WherePredicate::EqPredicate(WhereEqPredicate{ id, @@ -491,25 +492,25 @@ pub fn lower_where_predicate(_lctx: &LoweringContext, span}) => { hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { id: id, - path: lower_path(_lctx, path), - ty: lower_ty(_lctx, ty), + path: lower_path(lctx, path), + ty: lower_ty(lctx, ty), span: span, }) } } } -pub fn lower_variant_data(_lctx: &LoweringContext, vdata: &VariantData) -> hir::VariantData { +pub fn lower_variant_data(lctx: &LoweringContext, vdata: &VariantData) -> hir::VariantData { match *vdata { VariantData::Struct(ref fields, id) => { hir::VariantData::Struct(fields.iter() - .map(|f| lower_struct_field(_lctx, f)) + .map(|f| lower_struct_field(lctx, f)) .collect(), id) } VariantData::Tuple(ref fields, id) => { hir::VariantData::Tuple(fields.iter() - .map(|f| lower_struct_field(_lctx, f)) + .map(|f| lower_struct_field(lctx, f)) .collect(), id) } @@ -517,129 +518,129 @@ pub fn lower_variant_data(_lctx: &LoweringContext, vdata: &VariantData) -> hir:: } } -pub fn lower_trait_ref(_lctx: &LoweringContext, p: &TraitRef) -> hir::TraitRef { +pub fn lower_trait_ref(lctx: &LoweringContext, p: &TraitRef) -> hir::TraitRef { hir::TraitRef { - path: lower_path(_lctx, &p.path), + path: lower_path(lctx, &p.path), ref_id: p.ref_id, } } -pub fn lower_poly_trait_ref(_lctx: &LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { +pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { hir::PolyTraitRef { - bound_lifetimes: lower_lifetime_defs(_lctx, &p.bound_lifetimes), - trait_ref: lower_trait_ref(_lctx, &p.trait_ref), + bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes), + trait_ref: lower_trait_ref(lctx, &p.trait_ref), span: p.span, } } -pub fn lower_struct_field(_lctx: &LoweringContext, f: &StructField) -> hir::StructField { +pub fn lower_struct_field(lctx: &LoweringContext, f: &StructField) -> hir::StructField { Spanned { node: hir::StructField_ { id: f.node.id, - kind: lower_struct_field_kind(_lctx, &f.node.kind), - ty: lower_ty(_lctx, &f.node.ty), + kind: lower_struct_field_kind(lctx, &f.node.kind), + ty: lower_ty(lctx, &f.node.ty), attrs: f.node.attrs.clone(), }, span: f.span, } } -pub fn lower_field(_lctx: &LoweringContext, f: &Field) -> hir::Field { +pub fn lower_field(lctx: &LoweringContext, f: &Field) -> hir::Field { hir::Field { name: respan(f.ident.span, f.ident.node.name), - expr: lower_expr(_lctx, &f.expr), + expr: lower_expr(lctx, &f.expr), span: f.span, } } -pub fn lower_mt(_lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy { +pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy { hir::MutTy { - ty: lower_ty(_lctx, &mt.ty), - mutbl: lower_mutability(_lctx, mt.mutbl), + ty: lower_ty(lctx, &mt.ty), + mutbl: lower_mutability(lctx, mt.mutbl), } } -pub fn lower_opt_bounds(_lctx: &LoweringContext, +pub fn lower_opt_bounds(lctx: &LoweringContext, b: &Option>) -> Option> { - b.as_ref().map(|ref bounds| lower_bounds(_lctx, bounds)) + b.as_ref().map(|ref bounds| lower_bounds(lctx, bounds)) } -fn lower_bounds(_lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { - bounds.iter().map(|bound| lower_ty_param_bound(_lctx, bound)).collect() +fn lower_bounds(lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { + bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() } -pub fn lower_block(_lctx: &LoweringContext, b: &Block) -> P { +pub fn lower_block(lctx: &LoweringContext, b: &Block) -> P { P(hir::Block { id: b.id, - stmts: b.stmts.iter().map(|s| lower_stmt(_lctx, s)).collect(), - expr: b.expr.as_ref().map(|ref x| lower_expr(_lctx, x)), - rules: lower_block_check_mode(_lctx, &b.rules), + stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(), + expr: b.expr.as_ref().map(|ref x| lower_expr(lctx, x)), + rules: lower_block_check_mode(lctx, &b.rules), span: b.span, }) } -pub fn lower_item_underscore(_lctx: &LoweringContext, i: &Item_) -> hir::Item_ { +pub fn lower_item_underscore(lctx: &LoweringContext, i: &Item_) -> hir::Item_ { match *i { ItemExternCrate(string) => hir::ItemExternCrate(string), ItemUse(ref view_path) => { - hir::ItemUse(lower_view_path(_lctx, view_path)) + hir::ItemUse(lower_view_path(lctx, view_path)) } ItemStatic(ref t, m, ref e) => { - hir::ItemStatic(lower_ty(_lctx, t), - lower_mutability(_lctx, m), - lower_expr(_lctx, e)) + hir::ItemStatic(lower_ty(lctx, t), + lower_mutability(lctx, m), + lower_expr(lctx, e)) } ItemConst(ref t, ref e) => { - hir::ItemConst(lower_ty(_lctx, t), lower_expr(_lctx, e)) + hir::ItemConst(lower_ty(lctx, t), lower_expr(lctx, e)) } ItemFn(ref decl, unsafety, constness, abi, ref generics, ref body) => { - hir::ItemFn(lower_fn_decl(_lctx, decl), - lower_unsafety(_lctx, unsafety), - lower_constness(_lctx, constness), + hir::ItemFn(lower_fn_decl(lctx, decl), + lower_unsafety(lctx, unsafety), + lower_constness(lctx, constness), abi, - lower_generics(_lctx, generics), - lower_block(_lctx, body)) + lower_generics(lctx, generics), + lower_block(lctx, body)) } - ItemMod(ref m) => hir::ItemMod(lower_mod(_lctx, m)), - ItemForeignMod(ref nm) => hir::ItemForeignMod(lower_foreign_mod(_lctx, nm)), + ItemMod(ref m) => hir::ItemMod(lower_mod(lctx, m)), + ItemForeignMod(ref nm) => hir::ItemForeignMod(lower_foreign_mod(lctx, nm)), ItemTy(ref t, ref generics) => { - hir::ItemTy(lower_ty(_lctx, t), lower_generics(_lctx, generics)) + hir::ItemTy(lower_ty(lctx, t), lower_generics(lctx, generics)) } ItemEnum(ref enum_definition, ref generics) => { hir::ItemEnum(hir::EnumDef { variants: enum_definition.variants .iter() - .map(|x| lower_variant(_lctx, x)) + .map(|x| lower_variant(lctx, x)) .collect(), }, - lower_generics(_lctx, generics)) + lower_generics(lctx, generics)) } ItemStruct(ref struct_def, ref generics) => { - let struct_def = lower_variant_data(_lctx, struct_def); - hir::ItemStruct(struct_def, lower_generics(_lctx, generics)) + let struct_def = lower_variant_data(lctx, struct_def); + hir::ItemStruct(struct_def, lower_generics(lctx, generics)) } ItemDefaultImpl(unsafety, ref trait_ref) => { - hir::ItemDefaultImpl(lower_unsafety(_lctx, unsafety), - lower_trait_ref(_lctx, trait_ref)) + hir::ItemDefaultImpl(lower_unsafety(lctx, unsafety), + lower_trait_ref(lctx, trait_ref)) } ItemImpl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => { let new_impl_items = impl_items.iter() - .map(|item| lower_impl_item(_lctx, item)) + .map(|item| lower_impl_item(lctx, item)) .collect(); - let ifce = ifce.as_ref().map(|trait_ref| lower_trait_ref(_lctx, trait_ref)); - hir::ItemImpl(lower_unsafety(_lctx, unsafety), - lower_impl_polarity(_lctx, polarity), - lower_generics(_lctx, generics), + let ifce = ifce.as_ref().map(|trait_ref| lower_trait_ref(lctx, trait_ref)); + hir::ItemImpl(lower_unsafety(lctx, unsafety), + lower_impl_polarity(lctx, polarity), + lower_generics(lctx, generics), ifce, - lower_ty(_lctx, ty), + lower_ty(lctx, ty), new_impl_items) } ItemTrait(unsafety, ref generics, ref bounds, ref items) => { - let bounds = lower_bounds(_lctx, bounds); - let items = items.iter().map(|item| lower_trait_item(_lctx, item)).collect(); - hir::ItemTrait(lower_unsafety(_lctx, unsafety), - lower_generics(_lctx, generics), + let bounds = lower_bounds(lctx, bounds); + let items = items.iter().map(|item| lower_trait_item(lctx, item)).collect(); + hir::ItemTrait(lower_unsafety(lctx, unsafety), + lower_generics(lctx, generics), bounds, items) } @@ -647,63 +648,82 @@ pub fn lower_item_underscore(_lctx: &LoweringContext, i: &Item_) -> hir::Item_ { } } -pub fn lower_trait_item(_lctx: &LoweringContext, i: &TraitItem) -> P { +pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> P { P(hir::TraitItem { id: i.id, name: i.ident.name, attrs: i.attrs.clone(), node: match i.node { ConstTraitItem(ref ty, ref default) => { - hir::ConstTraitItem(lower_ty(_lctx, ty), - default.as_ref().map(|x| lower_expr(_lctx, x))) + hir::ConstTraitItem(lower_ty(lctx, ty), + default.as_ref().map(|x| lower_expr(lctx, x))) } MethodTraitItem(ref sig, ref body) => { - hir::MethodTraitItem(lower_method_sig(_lctx, sig), - body.as_ref().map(|x| lower_block(_lctx, x))) + hir::MethodTraitItem(lower_method_sig(lctx, sig), + body.as_ref().map(|x| lower_block(lctx, x))) } TypeTraitItem(ref bounds, ref default) => { - hir::TypeTraitItem(lower_bounds(_lctx, bounds), - default.as_ref().map(|x| lower_ty(_lctx, x))) + hir::TypeTraitItem(lower_bounds(lctx, bounds), + default.as_ref().map(|x| lower_ty(lctx, x))) } }, span: i.span, }) } -pub fn lower_impl_item(_lctx: &LoweringContext, i: &ImplItem) -> P { +pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> P { P(hir::ImplItem { id: i.id, name: i.ident.name, attrs: i.attrs.clone(), - vis: lower_visibility(_lctx, i.vis), + vis: lower_visibility(lctx, i.vis), node: match i.node { ImplItemKind::Const(ref ty, ref expr) => { - hir::ImplItemKind::Const(lower_ty(_lctx, ty), lower_expr(_lctx, expr)) + hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr)) } ImplItemKind::Method(ref sig, ref body) => { - hir::ImplItemKind::Method(lower_method_sig(_lctx, sig), lower_block(_lctx, body)) + hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body)) } - ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(_lctx, ty)), + ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)), ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), }, span: i.span, }) } -pub fn lower_mod(_lctx: &LoweringContext, m: &Mod) -> hir::Mod { +pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod { hir::Mod { inner: m.inner, - items: m.items.iter().map(|x| lower_item(_lctx, x)).collect(), + item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(), } } -pub fn lower_crate(_lctx: &LoweringContext, c: &Crate) -> hir::Crate { +struct ItemLowerer<'lcx, 'interner: 'lcx> { + items: BTreeMap, + lctx: &'lcx LoweringContext<'interner>, +} + +impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { + fn visit_item(&mut self, item: &'lcx Item) { + self.items.insert(item.id, lower_item(self.lctx, item)); + visit::walk_item(self, item); + } +} + +pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate { + let items = { + let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: lctx }; + visit::walk_crate(&mut item_lowerer, c); + item_lowerer.items + }; + hir::Crate { - module: lower_mod(_lctx, &c.module), + module: lower_mod(lctx, &c.module), attrs: c.attrs.clone(), config: c.config.clone(), span: c.span, - exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(_lctx, m)).collect(), + exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(lctx, m)).collect(), + items: items, } } @@ -721,51 +741,49 @@ pub fn lower_macro_def(_lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef { } } -// fold one item into possibly many items -pub fn lower_item(_lctx: &LoweringContext, i: &Item) -> P { - P(lower_item_simple(_lctx, i)) +pub fn lower_item_id(_lctx: &LoweringContext, i: &Item) -> hir::ItemId { + hir::ItemId { id: i.id } } -// fold one item into exactly one item -pub fn lower_item_simple(_lctx: &LoweringContext, i: &Item) -> hir::Item { - let node = lower_item_underscore(_lctx, &i.node); +pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { + let node = lower_item_underscore(lctx, &i.node); hir::Item { id: i.id, name: i.ident.name, attrs: i.attrs.clone(), node: node, - vis: lower_visibility(_lctx, i.vis), + vis: lower_visibility(lctx, i.vis), span: i.span, } } -pub fn lower_foreign_item(_lctx: &LoweringContext, i: &ForeignItem) -> P { +pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> P { P(hir::ForeignItem { id: i.id, name: i.ident.name, attrs: i.attrs.clone(), node: match i.node { ForeignItemFn(ref fdec, ref generics) => { - hir::ForeignItemFn(lower_fn_decl(_lctx, fdec), lower_generics(_lctx, generics)) + hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics)) } ForeignItemStatic(ref t, m) => { - hir::ForeignItemStatic(lower_ty(_lctx, t), m) + hir::ForeignItemStatic(lower_ty(lctx, t), m) } }, - vis: lower_visibility(_lctx, i.vis), + vis: lower_visibility(lctx, i.vis), span: i.span, }) } -pub fn lower_method_sig(_lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig { +pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig { hir::MethodSig { - generics: lower_generics(_lctx, &sig.generics), + generics: lower_generics(lctx, &sig.generics), abi: sig.abi, - explicit_self: lower_explicit_self(_lctx, &sig.explicit_self), - unsafety: lower_unsafety(_lctx, sig.unsafety), - constness: lower_constness(_lctx, sig.constness), - decl: lower_fn_decl(_lctx, &sig.decl), + explicit_self: lower_explicit_self(lctx, &sig.explicit_self), + unsafety: lower_unsafety(lctx, sig.unsafety), + constness: lower_constness(lctx, sig.constness), + decl: lower_fn_decl(lctx, &sig.decl), } } @@ -817,38 +835,38 @@ pub fn lower_binop(_lctx: &LoweringContext, b: BinOp) -> hir::BinOp { } } -pub fn lower_pat(_lctx: &LoweringContext, p: &Pat) -> P { +pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { P(hir::Pat { id: p.id, node: match p.node { PatWild => hir::PatWild, PatIdent(ref binding_mode, pth1, ref sub) => { - hir::PatIdent(lower_binding_mode(_lctx, binding_mode), + hir::PatIdent(lower_binding_mode(lctx, binding_mode), pth1, - sub.as_ref().map(|x| lower_pat(_lctx, x))) + sub.as_ref().map(|x| lower_pat(lctx, x))) } - PatLit(ref e) => hir::PatLit(lower_expr(_lctx, e)), + PatLit(ref e) => hir::PatLit(lower_expr(lctx, e)), PatEnum(ref pth, ref pats) => { - hir::PatEnum(lower_path(_lctx, pth), + hir::PatEnum(lower_path(lctx, pth), pats.as_ref() - .map(|pats| pats.iter().map(|x| lower_pat(_lctx, x)).collect())) + .map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect())) } PatQPath(ref qself, ref pth) => { let qself = hir::QSelf { - ty: lower_ty(_lctx, &qself.ty), + ty: lower_ty(lctx, &qself.ty), position: qself.position, }; - hir::PatQPath(qself, lower_path(_lctx, pth)) + hir::PatQPath(qself, lower_path(lctx, pth)) } PatStruct(ref pth, ref fields, etc) => { - let pth = lower_path(_lctx, pth); + let pth = lower_path(lctx, pth); let fs = fields.iter() .map(|f| { Spanned { span: f.span, node: hir::FieldPat { name: f.node.ident.name, - pat: lower_pat(_lctx, &f.node.pat), + pat: lower_pat(lctx, &f.node.pat), is_shorthand: f.node.is_shorthand, }, } @@ -856,18 +874,18 @@ pub fn lower_pat(_lctx: &LoweringContext, p: &Pat) -> P { .collect(); hir::PatStruct(pth, fs, etc) } - PatTup(ref elts) => hir::PatTup(elts.iter().map(|x| lower_pat(_lctx, x)).collect()), - PatBox(ref inner) => hir::PatBox(lower_pat(_lctx, inner)), + PatTup(ref elts) => hir::PatTup(elts.iter().map(|x| lower_pat(lctx, x)).collect()), + PatBox(ref inner) => hir::PatBox(lower_pat(lctx, inner)), PatRegion(ref inner, mutbl) => { - hir::PatRegion(lower_pat(_lctx, inner), lower_mutability(_lctx, mutbl)) + hir::PatRegion(lower_pat(lctx, inner), lower_mutability(lctx, mutbl)) } PatRange(ref e1, ref e2) => { - hir::PatRange(lower_expr(_lctx, e1), lower_expr(_lctx, e2)) + hir::PatRange(lower_expr(lctx, e1), lower_expr(lctx, e2)) } PatVec(ref before, ref slice, ref after) => { - hir::PatVec(before.iter().map(|x| lower_pat(_lctx, x)).collect(), - slice.as_ref().map(|x| lower_pat(_lctx, x)), - after.iter().map(|x| lower_pat(_lctx, x)).collect()) + hir::PatVec(before.iter().map(|x| lower_pat(lctx, x)).collect(), + slice.as_ref().map(|x| lower_pat(lctx, x)), + after.iter().map(|x| lower_pat(lctx, x)).collect()) } PatMac(_) => panic!("Shouldn't exist here"), }, @@ -875,19 +893,16 @@ pub fn lower_pat(_lctx: &LoweringContext, p: &Pat) -> P { }) } -// RAII utility for setting and unsetting the cached id. -struct CachedIdSetter<'a> { - reset: bool, - lctx: &'a LoweringContext<'a>, -} - -impl<'a> CachedIdSetter<'a> { - fn new(lctx: &'a LoweringContext, expr_id: NodeId) -> CachedIdSetter<'a> { - // Only reset the id if it was previously 0, i.e., was not cached. - // If it was cached, we are in a nested node, but our id count will - // still count towards the parent's count. - let reset_cached_id = lctx.cached_id.get() == 0; +// Utility fn for setting and unsetting the cached id. +fn cache_ids<'a, OP, R>(lctx: &LoweringContext, expr_id: NodeId, op: OP) -> R + where OP: FnOnce(&LoweringContext) -> R +{ + // Only reset the id if it was previously 0, i.e., was not cached. + // If it was cached, we are in a nested node, but our id count will + // still count towards the parent's count. + let reset_cached_id = lctx.cached_id.get() == 0; + { let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut(); if id_cache.contains_key(&expr_id) { @@ -907,21 +922,16 @@ impl<'a> CachedIdSetter<'a> { id_cache.insert(expr_id, next_id); lctx.gensym_key.set(next_id); } - - CachedIdSetter { - reset: reset_cached_id, - lctx: lctx, - } } -} -impl<'a> Drop for CachedIdSetter<'a> { - fn drop(&mut self) { - if self.reset { - self.lctx.cached_id.set(0); - self.lctx.gensym_key.set(0); - } + let result = op(lctx); + + if reset_cached_id { + lctx.cached_id.set(0); + lctx.gensym_key.set(0); } + + result } pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { @@ -959,129 +969,141 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); // InPlace::finalize(place) // }) - let _old_cached = CachedIdSetter::new(lctx, e.id); + return cache_ids(lctx, e.id, |lctx| { + let placer_expr = lower_expr(lctx, placer); + let value_expr = lower_expr(lctx, value_expr); + + let placer_ident = lctx.str_to_ident("placer"); + let place_ident = lctx.str_to_ident("place"); + let p_ptr_ident = lctx.str_to_ident("p_ptr"); + + let make_place = ["ops", "Placer", "make_place"]; + let place_pointer = ["ops", "Place", "pointer"]; + let move_val_init = ["intrinsics", "move_val_init"]; + let inplace_finalize = ["ops", "InPlace", "finalize"]; + + let make_call = |lctx: &LoweringContext, p, args| { + let path = core_path(lctx, e.span, p); + let path = expr_path(lctx, path); + expr_call(lctx, e.span, path, args) + }; - let placer_expr = lower_expr(lctx, placer); - let value_expr = lower_expr(lctx, value_expr); + let mk_stmt_let = |lctx: &LoweringContext, bind, expr| { + stmt_let(lctx, e.span, false, bind, expr) + }; - let placer_ident = lctx.str_to_ident("placer"); - let agent_ident = lctx.str_to_ident("place"); - let p_ptr_ident = lctx.str_to_ident("p_ptr"); + let mk_stmt_let_mut = |lctx: &LoweringContext, bind, expr| { + stmt_let(lctx, e.span, true, bind, expr) + }; - let make_place = ["ops", "Placer", "make_place"]; - let place_pointer = ["ops", "Place", "pointer"]; - let move_val_init = ["intrinsics", "move_val_init"]; - let inplace_finalize = ["ops", "InPlace", "finalize"]; + // let placer = ; + let s1 = { + let placer_expr = signal_block_expr(lctx, + vec![], + placer_expr, + e.span, + hir::PopUnstableBlock); + mk_stmt_let(lctx, placer_ident, placer_expr) + }; - let make_call = |lctx, p, args| { - let path = core_path(lctx, e.span, p); - let path = expr_path(lctx, path); - expr_call(lctx, e.span, path, args) - }; + // let mut place = Placer::make_place(placer); + let s2 = { + let placer = expr_ident(lctx, e.span, placer_ident); + let call = make_call(lctx, &make_place, vec![placer]); + mk_stmt_let_mut(lctx, place_ident, call) + }; - let mk_stmt_let = |lctx, bind, expr| stmt_let(lctx, e.span, false, bind, expr); - let mk_stmt_let_mut = |lctx, bind, expr| stmt_let(lctx, e.span, true, bind, expr); - - // let placer = ; - let s1 = mk_stmt_let(lctx, - placer_ident, - signal_block_expr(lctx, - vec![], - placer_expr, - e.span, - hir::PopUnstableBlock)); - - // let mut place = Placer::make_place(placer); - let s2 = { - let call = make_call(lctx, - &make_place, - vec![expr_ident(lctx, e.span, placer_ident)]); - mk_stmt_let_mut(lctx, agent_ident, call) - }; + // let p_ptr = Place::pointer(&mut place); + let s3 = { + let agent = expr_ident(lctx, e.span, place_ident); + let args = vec![expr_mut_addr_of(lctx, e.span, agent)]; + let call = make_call(lctx, &place_pointer, args); + mk_stmt_let(lctx, p_ptr_ident, call) + }; - // let p_ptr = Place::pointer(&mut place); - let s3 = { - let args = vec![expr_mut_addr_of(lctx, - e.span, - expr_ident(lctx, e.span, agent_ident))]; - let call = make_call(lctx, &place_pointer, args); - mk_stmt_let(lctx, p_ptr_ident, call) - }; + // pop_unsafe!(EXPR)); + let pop_unsafe_expr = { + let value_expr = signal_block_expr(lctx, + vec![], + value_expr, + e.span, + hir::PopUnstableBlock); + signal_block_expr(lctx, + vec![], + value_expr, + e.span, + hir::PopUnsafeBlock(hir::CompilerGenerated)) + }; - // pop_unsafe!(EXPR)); - let pop_unsafe_expr = - signal_block_expr(lctx, - vec![], - signal_block_expr(lctx, - vec![], - value_expr, - e.span, - hir::PopUnstableBlock), - e.span, - hir::PopUnsafeBlock(hir::CompilerGenerated)); + // push_unsafe!({ + // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); + // InPlace::finalize(place) + // }) + let expr = { + let ptr = expr_ident(lctx, e.span, p_ptr_ident); + let call_move_val_init = + hir::StmtSemi( + make_call(lctx, &move_val_init, vec![ptr, pop_unsafe_expr]), + lctx.next_id()); + let call_move_val_init = respan(e.span, call_move_val_init); + + let place = expr_ident(lctx, e.span, place_ident); + let call = make_call(lctx, &inplace_finalize, vec![place]); + signal_block_expr(lctx, + vec![P(call_move_val_init)], + call, + e.span, + hir::PushUnsafeBlock(hir::CompilerGenerated)) + }; - // push_unsafe!({ - // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); - // InPlace::finalize(place) - // }) - let expr = { - let call_move_val_init = - hir::StmtSemi(make_call(lctx, - &move_val_init, - vec![expr_ident(lctx, e.span, p_ptr_ident), - pop_unsafe_expr]), - lctx.next_id()); - let call_move_val_init = respan(e.span, call_move_val_init); - - let call = make_call(lctx, - &inplace_finalize, - vec![expr_ident(lctx, e.span, agent_ident)]); signal_block_expr(lctx, - vec![P(call_move_val_init)], - call, + vec![s1, s2, s3], + expr, e.span, - hir::PushUnsafeBlock(hir::CompilerGenerated)) - }; - - return signal_block_expr(lctx, - vec![s1, s2, s3], - expr, - e.span, - hir::PushUnstableBlock); + hir::PushUnstableBlock) + }); } ExprVec(ref exprs) => { hir::ExprVec(exprs.iter().map(|x| lower_expr(lctx, x)).collect()) } ExprRepeat(ref expr, ref count) => { - hir::ExprRepeat(lower_expr(lctx, expr), lower_expr(lctx, count)) + let expr = lower_expr(lctx, expr); + let count = lower_expr(lctx, count); + hir::ExprRepeat(expr, count) } ExprTup(ref elts) => { hir::ExprTup(elts.iter().map(|x| lower_expr(lctx, x)).collect()) } ExprCall(ref f, ref args) => { - hir::ExprCall(lower_expr(lctx, f), - args.iter().map(|x| lower_expr(lctx, x)).collect()) + let f = lower_expr(lctx, f); + hir::ExprCall(f, args.iter().map(|x| lower_expr(lctx, x)).collect()) } ExprMethodCall(i, ref tps, ref args) => { - hir::ExprMethodCall(respan(i.span, i.node.name), - tps.iter().map(|x| lower_ty(lctx, x)).collect(), - args.iter().map(|x| lower_expr(lctx, x)).collect()) + let tps = tps.iter().map(|x| lower_ty(lctx, x)).collect(); + let args = args.iter().map(|x| lower_expr(lctx, x)).collect(); + hir::ExprMethodCall(respan(i.span, i.node.name), tps, args) } ExprBinary(binop, ref lhs, ref rhs) => { - hir::ExprBinary(lower_binop(lctx, binop), - lower_expr(lctx, lhs), - lower_expr(lctx, rhs)) + let binop = lower_binop(lctx, binop); + let lhs = lower_expr(lctx, lhs); + let rhs = lower_expr(lctx, rhs); + hir::ExprBinary(binop, lhs, rhs) } ExprUnary(op, ref ohs) => { - hir::ExprUnary(lower_unop(lctx, op), lower_expr(lctx, ohs)) + let op = lower_unop(lctx, op); + let ohs = lower_expr(lctx, ohs); + hir::ExprUnary(op, ohs) } ExprLit(ref l) => hir::ExprLit(P((**l).clone())), ExprCast(ref expr, ref ty) => { - hir::ExprCast(lower_expr(lctx, expr), lower_ty(lctx, ty)) + let expr = lower_expr(lctx, expr); + hir::ExprCast(expr, lower_ty(lctx, ty)) } ExprAddrOf(m, ref ohs) => { - hir::ExprAddrOf(lower_mutability(lctx, m), lower_expr(lctx, ohs)) + let m = lower_mutability(lctx, m); + let ohs = lower_expr(lctx, ohs); + hir::ExprAddrOf(m, ohs) } // More complicated than you might expect because the else branch // might be `if let`. @@ -1089,17 +1111,20 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { let else_opt = else_opt.as_ref().map(|els| { match els.node { ExprIfLet(..) => { - let _old_cached = CachedIdSetter::new(lctx, e.id); - // wrap the if-let expr in a block - let span = els.span; - let blk = P(hir::Block { - stmts: vec![], - expr: Some(lower_expr(lctx, els)), - id: lctx.next_id(), - rules: hir::DefaultBlock, - span: span, - }); - expr_block(lctx, blk) + cache_ids(lctx, e.id, |lctx| { + // wrap the if-let expr in a block + let span = els.span; + let els = lower_expr(lctx, els); + let id = lctx.next_id(); + let blk = P(hir::Block { + stmts: vec![], + expr: Some(els), + id: id, + rules: hir::DefaultBlock, + span: span, + }); + expr_block(lctx, blk) + }) } _ => lower_expr(lctx, els), } @@ -1204,76 +1229,79 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { // _ => [ | ()] // } - let _old_cached = CachedIdSetter::new(lctx, e.id); - - // ` => ` - let pat_arm = { - let body_expr = expr_block(lctx, lower_block(lctx, body)); - arm(vec![lower_pat(lctx, pat)], body_expr) - }; + return cache_ids(lctx, e.id, |lctx| { + // ` => ` + let pat_arm = { + let body = lower_block(lctx, body); + let body_expr = expr_block(lctx, body); + arm(vec![lower_pat(lctx, pat)], body_expr) + }; - // `[_ if => ,]` - let mut else_opt = else_opt.as_ref().map(|e| lower_expr(lctx, e)); - let else_if_arms = { - let mut arms = vec![]; - loop { - let else_opt_continue = else_opt.and_then(|els| { - els.and_then(|els| { - match els.node { - // else if - hir::ExprIf(cond, then, else_opt) => { - let pat_under = pat_wild(lctx, e.span); - arms.push(hir::Arm { - attrs: vec![], - pats: vec![pat_under], - guard: Some(cond), - body: expr_block(lctx, then), - }); - else_opt.map(|else_opt| (else_opt, true)) + // `[_ if => ,]` + let mut else_opt = else_opt.as_ref().map(|e| lower_expr(lctx, e)); + let else_if_arms = { + let mut arms = vec![]; + loop { + let else_opt_continue = else_opt.and_then(|els| { + els.and_then(|els| { + match els.node { + // else if + hir::ExprIf(cond, then, else_opt) => { + let pat_under = pat_wild(lctx, e.span); + arms.push(hir::Arm { + attrs: vec![], + pats: vec![pat_under], + guard: Some(cond), + body: expr_block(lctx, then), + }); + else_opt.map(|else_opt| (else_opt, true)) + } + _ => Some((P(els), false)), } - _ => Some((P(els), false)), + }) + }); + match else_opt_continue { + Some((e, true)) => { + else_opt = Some(e); + } + Some((e, false)) => { + else_opt = Some(e); + break; + } + None => { + else_opt = None; + break; } - }) - }); - match else_opt_continue { - Some((e, true)) => { - else_opt = Some(e); - } - Some((e, false)) => { - else_opt = Some(e); - break; - } - None => { - else_opt = None; - break; } } - } - arms - }; + arms + }; - let contains_else_clause = else_opt.is_some(); + let contains_else_clause = else_opt.is_some(); - // `_ => [ | ()]` - let else_arm = { - let pat_under = pat_wild(lctx, e.span); - let else_expr = else_opt.unwrap_or_else(|| expr_tuple(lctx, e.span, vec![])); - arm(vec![pat_under], else_expr) - }; + // `_ => [ | ()]` + let else_arm = { + let pat_under = pat_wild(lctx, e.span); + let else_expr = + else_opt.unwrap_or_else( + || expr_tuple(lctx, e.span, vec![])); + arm(vec![pat_under], else_expr) + }; - let mut arms = Vec::with_capacity(else_if_arms.len() + 2); - arms.push(pat_arm); - arms.extend(else_if_arms); - arms.push(else_arm); + let mut arms = Vec::with_capacity(else_if_arms.len() + 2); + arms.push(pat_arm); + arms.extend(else_if_arms); + arms.push(else_arm); - let match_expr = expr(lctx, - e.span, - hir::ExprMatch(lower_expr(lctx, sub_expr), - arms, - hir::MatchSource::IfLetDesugar { - contains_else_clause: contains_else_clause, - })); - return match_expr; + let sub_expr = lower_expr(lctx, sub_expr); + expr(lctx, + e.span, + hir::ExprMatch(sub_expr, + arms, + hir::MatchSource::IfLetDesugar { + contains_else_clause: contains_else_clause, + })) + }); } // Desugar ExprWhileLet @@ -1288,32 +1316,34 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { // } // } - let _old_cached = CachedIdSetter::new(lctx, e.id); - - // ` => ` - let pat_arm = { - let body_expr = expr_block(lctx, lower_block(lctx, body)); - arm(vec![lower_pat(lctx, pat)], body_expr) - }; - - // `_ => break` - let break_arm = { - let pat_under = pat_wild(lctx, e.span); - let break_expr = expr_break(lctx, e.span); - arm(vec![pat_under], break_expr) - }; + return cache_ids(lctx, e.id, |lctx| { + // ` => ` + let pat_arm = { + let body = lower_block(lctx, body); + let body_expr = expr_block(lctx, body); + arm(vec![lower_pat(lctx, pat)], body_expr) + }; - // `match { ... }` - let arms = vec![pat_arm, break_arm]; - let match_expr = expr(lctx, - e.span, - hir::ExprMatch(lower_expr(lctx, sub_expr), - arms, - hir::MatchSource::WhileLetDesugar)); + // `_ => break` + let break_arm = { + let pat_under = pat_wild(lctx, e.span); + let break_expr = expr_break(lctx, e.span); + arm(vec![pat_under], break_expr) + }; - // `[opt_ident]: loop { ... }` - let loop_block = block_expr(lctx, match_expr); - return expr(lctx, e.span, hir::ExprLoop(loop_block, opt_ident)); + // `match { ... }` + let arms = vec![pat_arm, break_arm]; + let sub_expr = lower_expr(lctx, sub_expr); + let match_expr = expr(lctx, + e.span, + hir::ExprMatch(sub_expr, + arms, + hir::MatchSource::WhileLetDesugar)); + + // `[opt_ident]: loop { ... }` + let loop_block = block_expr(lctx, match_expr); + expr(lctx, e.span, hir::ExprLoop(loop_block, opt_ident)) + }); } // Desugar ExprForLoop @@ -1335,97 +1365,90 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { // result // } - let _old_cached = CachedIdSetter::new(lctx, e.id); - - // expand - let head = lower_expr(lctx, head); + return cache_ids(lctx, e.id, |lctx| { + // expand + let head = lower_expr(lctx, head); - let iter = lctx.str_to_ident("iter"); + let iter = lctx.str_to_ident("iter"); - // `::std::option::Option::Some() => ` - let pat_arm = { - let body_block = lower_block(lctx, body); - let body_span = body_block.span; - let body_expr = P(hir::Expr { - id: lctx.next_id(), - node: hir::ExprBlock(body_block), - span: body_span, - }); - let pat = lower_pat(lctx, pat); - let some_pat = pat_some(lctx, e.span, pat); - - arm(vec![some_pat], body_expr) - }; + // `::std::option::Option::Some() => ` + let pat_arm = { + let body_block = lower_block(lctx, body); + let body_span = body_block.span; + let body_expr = P(hir::Expr { + id: lctx.next_id(), + node: hir::ExprBlock(body_block), + span: body_span, + }); + let pat = lower_pat(lctx, pat); + let some_pat = pat_some(lctx, e.span, pat); - // `::std::option::Option::None => break` - let break_arm = { - let break_expr = expr_break(lctx, e.span); + arm(vec![some_pat], body_expr) + }; - arm(vec![pat_none(lctx, e.span)], break_expr) - }; + // `::std::option::Option::None => break` + let break_arm = { + let break_expr = expr_break(lctx, e.span); - // `match ::std::iter::Iterator::next(&mut iter) { ... }` - let match_expr = { - let next_path = { - let strs = std_path(lctx, &["iter", "Iterator", "next"]); + arm(vec![pat_none(lctx, e.span)], break_expr) + }; - path_global(e.span, strs) + // `match ::std::iter::Iterator::next(&mut iter) { ... }` + let match_expr = { + let next_path = { + let strs = std_path(lctx, &["iter", "Iterator", "next"]); + + path_global(e.span, strs) + }; + let iter = expr_ident(lctx, e.span, iter); + let ref_mut_iter = expr_mut_addr_of(lctx, e.span, iter); + let next_path = expr_path(lctx, next_path); + let next_expr = expr_call(lctx, e.span, next_path, vec![ref_mut_iter]); + let arms = vec![pat_arm, break_arm]; + + expr(lctx, + e.span, + hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar)) }; - let ref_mut_iter = expr_mut_addr_of(lctx, - e.span, - expr_ident(lctx, e.span, iter)); - let next_expr = expr_call(lctx, - e.span, - expr_path(lctx, next_path), - vec![ref_mut_iter]); - let arms = vec![pat_arm, break_arm]; - expr(lctx, - e.span, - hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar)) - }; + // `[opt_ident]: loop { ... }` + let loop_block = block_expr(lctx, match_expr); + let loop_expr = expr(lctx, e.span, hir::ExprLoop(loop_block, opt_ident)); + + // `mut iter => { ... }` + let iter_arm = { + let iter_pat = pat_ident_binding_mode(lctx, + e.span, + iter, + hir::BindByValue(hir::MutMutable)); + arm(vec![iter_pat], loop_expr) + }; - // `[opt_ident]: loop { ... }` - let loop_block = block_expr(lctx, match_expr); - let loop_expr = expr(lctx, e.span, hir::ExprLoop(loop_block, opt_ident)); - - // `mut iter => { ... }` - let iter_arm = { - let iter_pat = pat_ident_binding_mode(lctx, - e.span, - iter, - hir::BindByValue(hir::MutMutable)); - arm(vec![iter_pat], loop_expr) - }; + // `match ::std::iter::IntoIterator::into_iter() { ... }` + let into_iter_expr = { + let into_iter_path = { + let strs = std_path(lctx, &["iter", "IntoIterator", "into_iter"]); - // `match ::std::iter::IntoIterator::into_iter() { ... }` - let into_iter_expr = { - let into_iter_path = { - let strs = std_path(lctx, &["iter", "IntoIterator", "into_iter"]); + path_global(e.span, strs) + }; - path_global(e.span, strs) + let into_iter = expr_path(lctx, into_iter_path); + expr_call(lctx, e.span, into_iter, vec![head]) }; - expr_call(lctx, e.span, expr_path(lctx, into_iter_path), vec![head]) - }; - - let match_expr = expr_match(lctx, - e.span, - into_iter_expr, - vec![iter_arm], - hir::MatchSource::ForLoopDesugar); - - // `{ let result = ...; result }` - let result_ident = lctx.str_to_ident("result"); - return expr_block(lctx, - block_all(lctx, - e.span, - vec![stmt_let(lctx, - e.span, - false, - result_ident, - match_expr)], - Some(expr_ident(lctx, e.span, result_ident)))); + let match_expr = expr_match(lctx, + e.span, + into_iter_expr, + vec![iter_arm], + hir::MatchSource::ForLoopDesugar); + + // `{ let result = ...; result }` + let result_ident = lctx.str_to_ident("result"); + let let_stmt = stmt_let(lctx, e.span, false, result_ident, match_expr); + let result = expr_ident(lctx, e.span, result_ident); + let block = block_all(lctx, e.span, vec![let_stmt], Some(result)); + expr_block(lctx, block) + }); } ExprMac(_) => panic!("Shouldn't exist here"), @@ -1434,23 +1457,23 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { }) } -pub fn lower_stmt(_lctx: &LoweringContext, s: &Stmt) -> P { +pub fn lower_stmt(lctx: &LoweringContext, s: &Stmt) -> P { match s.node { StmtDecl(ref d, id) => { P(Spanned { - node: hir::StmtDecl(lower_decl(_lctx, d), id), + node: hir::StmtDecl(lower_decl(lctx, d), id), span: s.span, }) } StmtExpr(ref e, id) => { P(Spanned { - node: hir::StmtExpr(lower_expr(_lctx, e), id), + node: hir::StmtExpr(lower_expr(lctx, e), id), span: s.span, }) } StmtSemi(ref e, id) => { P(Spanned { - node: hir::StmtSemi(lower_expr(_lctx, e), id), + node: hir::StmtSemi(lower_expr(lctx, e), id), span: s.span, }) } @@ -1472,26 +1495,26 @@ pub fn lower_visibility(_lctx: &LoweringContext, v: Visibility) -> hir::Visibili } } -pub fn lower_block_check_mode(_lctx: &LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { +pub fn lower_block_check_mode(lctx: &LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { match *b { DefaultBlock => hir::DefaultBlock, - UnsafeBlock(u) => hir::UnsafeBlock(lower_unsafe_source(_lctx, u)), + UnsafeBlock(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)), } } -pub fn lower_binding_mode(_lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode { +pub fn lower_binding_mode(lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode { match *b { - BindByRef(m) => hir::BindByRef(lower_mutability(_lctx, m)), - BindByValue(m) => hir::BindByValue(lower_mutability(_lctx, m)), + BindByRef(m) => hir::BindByRef(lower_mutability(lctx, m)), + BindByValue(m) => hir::BindByValue(lower_mutability(lctx, m)), } } -pub fn lower_struct_field_kind(_lctx: &LoweringContext, +pub fn lower_struct_field_kind(lctx: &LoweringContext, s: &StructFieldKind) -> hir::StructFieldKind { match *s { - NamedField(ident, vis) => hir::NamedField(ident.name, lower_visibility(_lctx, vis)), - UnnamedField(vis) => hir::UnnamedField(lower_visibility(_lctx, vis)), + NamedField(ident, vis) => hir::NamedField(ident.name, lower_visibility(lctx, vis)), + UnnamedField(vis) => hir::UnnamedField(lower_visibility(lctx, vis)), } } @@ -1734,11 +1757,12 @@ fn signal_block_expr(lctx: &LoweringContext, span: Span, rule: hir::BlockCheckMode) -> P { + let id = lctx.next_id(); expr_block(lctx, P(hir::Block { rules: rule, span: span, - id: lctx.next_id(), + id: id, stmts: stmts, expr: Some(expr), })) diff --git a/src/librustc_front/print/pprust.rs b/src/librustc_front/print/pprust.rs index 09c814449a9bc..e059a4ed5f69d 100644 --- a/src/librustc_front/print/pprust.rs +++ b/src/librustc_front/print/pprust.rs @@ -25,7 +25,7 @@ use syntax::print::pprust::{self as ast_pp, PrintState}; use syntax::ptr::P; use hir; -use hir::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; +use hir::{Crate, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use std::io::{self, Write, Read}; @@ -54,6 +54,7 @@ impl PpAnn for NoAnn {} pub struct State<'a> { + krate: Option<&'a Crate>, pub s: pp::Printer<'a>, cm: Option<&'a CodeMap>, comments: Option>, @@ -85,13 +86,17 @@ impl<'a> PrintState<'a> for State<'a> { } } -pub fn rust_printer<'a>(writer: Box) -> State<'a> { +pub fn rust_printer<'a>(writer: Box, krate: Option<&'a Crate>) -> State<'a> { static NO_ANN: NoAnn = NoAnn; - rust_printer_annotated(writer, &NO_ANN) + rust_printer_annotated(writer, &NO_ANN, krate) } -pub fn rust_printer_annotated<'a>(writer: Box, ann: &'a PpAnn) -> State<'a> { +pub fn rust_printer_annotated<'a>(writer: Box, + ann: &'a PpAnn, + krate: Option<&'a Crate>) + -> State<'a> { State { + krate: krate, s: pp::mk_printer(writer, default_columns), cm: None, comments: None, @@ -124,7 +129,8 @@ pub fn print_crate<'a>(cm: &'a CodeMap, ann: &'a PpAnn, is_expanded: bool) -> io::Result<()> { - let mut s = State::new_from_input(cm, span_diagnostic, filename, input, out, ann, is_expanded); + let mut s = State::new_from_input(cm, span_diagnostic, filename, input, + out, ann, is_expanded, Some(krate)); // When printing the AST, we sometimes need to inject `#[no_std]` here. // Since you can't compile the HIR, it's not necessary. @@ -141,7 +147,8 @@ impl<'a> State<'a> { input: &mut Read, out: Box, ann: &'a PpAnn, - is_expanded: bool) + is_expanded: bool, + krate: Option<&'a Crate>) -> State<'a> { let (cmnts, lits) = comments::gather_comments_and_literals(span_diagnostic, filename, @@ -158,16 +165,19 @@ impl<'a> State<'a> { None } else { Some(lits) - }) + }, + krate) } pub fn new(cm: &'a CodeMap, out: Box, ann: &'a PpAnn, comments: Option>, - literals: Option>) + literals: Option>, + krate: Option<&'a Crate>) -> State<'a> { State { + krate: krate, s: pp::mk_printer(out, default_columns), cm: Some(cm), comments: comments.clone(), @@ -187,7 +197,7 @@ pub fn to_string(f: F) -> String { let mut wr = Vec::new(); { - let mut printer = rust_printer(Box::new(&mut wr)); + let mut printer = rust_printer(Box::new(&mut wr), None); f(&mut printer).unwrap(); eof(&mut printer.s).unwrap(); } @@ -451,8 +461,8 @@ impl<'a> State<'a> { pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) -> io::Result<()> { try!(self.print_inner_attributes(attrs)); - for item in &_mod.items { - try!(self.print_item(&**item)); + for item_id in &_mod.item_ids { + try!(self.print_item_id(item_id)); } Ok(()) } @@ -620,6 +630,16 @@ impl<'a> State<'a> { word(&mut self.s, ";") } + pub fn print_item_id(&mut self, item_id: &hir::ItemId) -> io::Result<()> { + if let Some(krate) = self.krate { + // skip nested items if krate context was not provided + let item = &krate.items[&item_id.id]; + self.print_item(item) + } else { + Ok(()) + } + } + /// Pretty-print an item pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); @@ -1566,7 +1586,9 @@ impl<'a> State<'a> { } self.end() } - hir::DeclItem(ref item) => self.print_item(&**item), + hir::DeclItem(ref item) => { + self.print_item_id(item) + } } } diff --git a/src/librustc_front/util.rs b/src/librustc_front/util.rs index a2c52b274d55f..97b25dafb6dec 100644 --- a/src/librustc_front/util.rs +++ b/src/librustc_front/util.rs @@ -10,7 +10,7 @@ use hir; use hir::*; -use visit::{self, Visitor, FnKind}; +use intravisit::{self, Visitor, FnKind}; use syntax::ast_util; use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID}; use syntax::codemap::Span; @@ -145,12 +145,26 @@ pub fn unop_to_string(op: UnOp) -> &'static str { } pub struct IdVisitor<'a, O: 'a> { - pub operation: &'a mut O, - pub pass_through_items: bool, - pub visited_outermost: bool, + operation: &'a mut O, + + // In general, the id visitor visits the contents of an item, but + // not including nested trait/impl items, nor other nested items. + // The base visitor itself always skips nested items, but not + // trait/impl items. This means in particular that if you start by + // visiting a trait or an impl, you should not visit the + // trait/impl items respectively. This is handled by setting + // `skip_members` to true when `visit_item` is on the stack. This + // way, if the user begins by calling `visit_trait_item`, we will + // visit the trait item, but if they begin with `visit_item`, we + // won't visit the (nested) trait items. + skip_members: bool, } impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> { + pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> { + IdVisitor { operation: operation, skip_members: false } + } + fn visit_generics_helper(&mut self, generics: &Generics) { for type_parameter in generics.ty_params.iter() { self.operation.visit_id(type_parameter.id) @@ -164,22 +178,17 @@ impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> { impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) { self.operation.visit_id(node_id); - visit::walk_mod(self, module) + intravisit::walk_mod(self, module) } fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { self.operation.visit_id(foreign_item.id); - visit::walk_foreign_item(self, foreign_item) + intravisit::walk_foreign_item(self, foreign_item) } fn visit_item(&mut self, item: &Item) { - if !self.pass_through_items { - if self.visited_outermost { - return; - } else { - self.visited_outermost = true - } - } + assert!(!self.skip_members); + self.skip_members = true; self.operation.visit_id(item.id); match item.node { @@ -196,45 +205,44 @@ impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> } _ => {} } + intravisit::walk_item(self, item); - visit::walk_item(self, item); - - self.visited_outermost = false + self.skip_members = false; } fn visit_local(&mut self, local: &Local) { self.operation.visit_id(local.id); - visit::walk_local(self, local) + intravisit::walk_local(self, local) } fn visit_block(&mut self, block: &Block) { self.operation.visit_id(block.id); - visit::walk_block(self, block) + intravisit::walk_block(self, block) } fn visit_stmt(&mut self, statement: &Stmt) { self.operation.visit_id(stmt_id(statement)); - visit::walk_stmt(self, statement) + intravisit::walk_stmt(self, statement) } fn visit_pat(&mut self, pattern: &Pat) { self.operation.visit_id(pattern.id); - visit::walk_pat(self, pattern) + intravisit::walk_pat(self, pattern) } fn visit_expr(&mut self, expression: &Expr) { self.operation.visit_id(expression.id); - visit::walk_expr(self, expression) + intravisit::walk_expr(self, expression) } fn visit_ty(&mut self, typ: &Ty) { self.operation.visit_id(typ.id); - visit::walk_ty(self, typ) + intravisit::walk_ty(self, typ) } fn visit_generics(&mut self, generics: &Generics) { self.visit_generics_helper(generics); - visit::walk_generics(self, generics) + intravisit::walk_generics(self, generics) } fn visit_fn(&mut self, @@ -243,14 +251,6 @@ impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> block: &'v Block, span: Span, node_id: NodeId) { - if !self.pass_through_items { - match function_kind { - FnKind::Method(..) if self.visited_outermost => return, - FnKind::Method(..) => self.visited_outermost = true, - _ => {} - } - } - self.operation.visit_id(node_id); match function_kind { @@ -267,18 +267,12 @@ impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> self.operation.visit_id(argument.id) } - visit::walk_fn(self, function_kind, function_declaration, block, span); - - if !self.pass_through_items { - if let FnKind::Method(..) = function_kind { - self.visited_outermost = false; - } - } + intravisit::walk_fn(self, function_kind, function_declaration, block, span); } fn visit_struct_field(&mut self, struct_field: &StructField) { self.operation.visit_id(struct_field.node.id); - visit::walk_struct_field(self, struct_field) + intravisit::walk_struct_field(self, struct_field) } fn visit_variant_data(&mut self, @@ -288,17 +282,21 @@ impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> _: NodeId, _: Span) { self.operation.visit_id(struct_def.id()); - visit::walk_struct_def(self, struct_def); + intravisit::walk_struct_def(self, struct_def); } fn visit_trait_item(&mut self, ti: &hir::TraitItem) { - self.operation.visit_id(ti.id); - visit::walk_trait_item(self, ti); + if !self.skip_members { + self.operation.visit_id(ti.id); + intravisit::walk_trait_item(self, ti); + } } fn visit_impl_item(&mut self, ii: &hir::ImplItem) { - self.operation.visit_id(ii.id); - visit::walk_impl_item(self, ii); + if !self.skip_members { + self.operation.visit_id(ii.id); + intravisit::walk_impl_item(self, ii); + } } fn visit_lifetime(&mut self, lifetime: &Lifetime) { @@ -311,7 +309,7 @@ impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> fn visit_trait_ref(&mut self, trait_ref: &TraitRef) { self.operation.visit_id(trait_ref.ref_id); - visit::walk_trait_ref(self, trait_ref); + intravisit::walk_trait_ref(self, trait_ref); } } @@ -323,11 +321,7 @@ pub fn compute_id_range_for_fn_body(fk: FnKind, id: NodeId) -> ast_util::IdRange { let mut visitor = ast_util::IdRangeComputingVisitor { result: ast_util::IdRange::max() }; - let mut id_visitor = IdVisitor { - operation: &mut visitor, - pass_through_items: false, - visited_outermost: false, - }; + let mut id_visitor = IdVisitor::new(&mut visitor); id_visitor.visit_fn(fk, decl, body, sp, id); id_visitor.operation.result } diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index 53fc0824d9673..2146dc8e9b94b 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -18,7 +18,7 @@ use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::Span; use rustc_front::hir; -use rustc_front::visit::FnKind; +use rustc_front::intravisit::FnKind; #[derive(PartialEq)] pub enum MethodLateContext { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 3e43a2240de04..d24c336dd3fbd 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -46,7 +46,7 @@ use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::{self, Span}; use rustc_front::hir; -use rustc_front::visit::FnKind; +use rustc_front::intravisit::FnKind; use bad_style::{MethodLateContext, method_context}; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index abbb733d8848d..a1d029025b2fa 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -28,7 +28,7 @@ use syntax::feature_gate::{emit_feature_err, GateIssue}; use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64}; use rustc_front::hir; -use rustc_front::visit::{self, Visitor}; +use rustc_front::intravisit::{self, Visitor}; use rustc_front::util::is_shift_binop; declare_lint! { @@ -626,7 +626,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> { "found Rust tuple type in foreign module; \ consider using a struct instead`") } - _ => visit::walk_ty(self, ty) + _ => intravisit::walk_ty(self, ty) } } } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 2384b3987f253..c6494dc81f939 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -27,7 +27,7 @@ use syntax::ptr::P; use rustc_back::slice; use rustc_front::hir; -use rustc_front::visit::FnKind; +use rustc_front::intravisit::FnKind; declare_lint! { pub UNUSED_MUT, diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index a6b7169e18b40..34ef7c3487f73 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -33,7 +33,7 @@ use self::rustc::middle::ty::{self, Ty}; use self::rustc::util::common::ErrorReported; use self::rustc::util::nodemap::NodeMap; use self::rustc_front::hir; -use self::rustc_front::visit; +use self::rustc_front::intravisit::{self, Visitor}; use self::syntax::ast; use self::syntax::attr::AttrMetaMethods; use self::syntax::codemap::Span; @@ -47,7 +47,7 @@ pub fn build_mir_for_crate<'tcx>(tcx: &ty::ctxt<'tcx>) -> MirMap<'tcx> { tcx: tcx, map: &mut map, }; - visit::walk_crate(&mut dump, tcx.map.krate()); + tcx.map.krate().visit_all_items(&mut dump); } map } @@ -79,32 +79,32 @@ impl<'a, 'tcx> OuterDump<'a, 'tcx> { } -impl<'a, 'tcx> visit::Visitor<'tcx> for OuterDump<'a, 'tcx> { +impl<'a, 'tcx> Visitor<'tcx> for OuterDump<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { - self.visit_mir(&item.attrs, |c| visit::walk_item(c, item)); - visit::walk_item(self, item); + self.visit_mir(&item.attrs, |c| intravisit::walk_item(c, item)); + intravisit::walk_item(self, item); } fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { match trait_item.node { hir::MethodTraitItem(_, Some(_)) => { - self.visit_mir(&trait_item.attrs, |c| visit::walk_trait_item(c, trait_item)); + self.visit_mir(&trait_item.attrs, |c| intravisit::walk_trait_item(c, trait_item)); } hir::MethodTraitItem(_, None) | hir::ConstTraitItem(..) | hir::TypeTraitItem(..) => {} } - visit::walk_trait_item(self, trait_item); + intravisit::walk_trait_item(self, trait_item); } fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { match impl_item.node { hir::ImplItemKind::Method(..) => { - self.visit_mir(&impl_item.attrs, |c| visit::walk_impl_item(c, impl_item)); + self.visit_mir(&impl_item.attrs, |c| intravisit::walk_impl_item(c, impl_item)); } hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(..) => {} } - visit::walk_impl_item(self, impl_item); + intravisit::walk_impl_item(self, impl_item); } } @@ -117,27 +117,23 @@ struct InnerDump<'a, 'm, 'tcx: 'a + 'm> { attr: Option<&'a ast::Attribute>, } -impl<'a, 'm, 'tcx> visit::Visitor<'tcx> for InnerDump<'a,'m,'tcx> { - fn visit_item(&mut self, _: &'tcx hir::Item) { - // ignore nested items; they need their own graphviz annotation - } - +impl<'a, 'm, 'tcx> Visitor<'tcx> for InnerDump<'a,'m,'tcx> { fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { - // ignore nested items; they need their own graphviz annotation + // ignore methods; the outer dump will call us for them independently } fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { - // ignore nested items; they need their own graphviz annotation + // ignore methods; the outer dump will call us for them independently } fn visit_fn(&mut self, - fk: visit::FnKind<'tcx>, + fk: intravisit::FnKind<'tcx>, decl: &'tcx hir::FnDecl, body: &'tcx hir::Block, span: Span, id: ast::NodeId) { let (prefix, implicit_arg_tys) = match fk { - visit::FnKind::Closure => + intravisit::FnKind::Closure => (format!("{}-", id), vec![closure_self_ty(&self.tcx, id, body.id)]), _ => (format!(""), vec![]), @@ -188,7 +184,7 @@ impl<'a, 'm, 'tcx> visit::Visitor<'tcx> for InnerDump<'a,'m,'tcx> { Err(ErrorReported) => {} } - visit::walk_fn(self, fk, decl, body, span); + intravisit::walk_fn(self, fk, decl, body, span); } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 09503bec0c360..d11880ecca19b 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -35,7 +35,7 @@ use self::FieldName::*; use std::mem::replace; use rustc_front::hir; -use rustc_front::visit::{self, Visitor}; +use rustc_front::intravisit::{self, Visitor}; use rustc::middle::def; use rustc::middle::def_id::DefId; @@ -63,12 +63,18 @@ type CheckResult = Option<(Span, String, Option<(Span, String)>)>; /// The parent visitor, used to determine what's the parent of what (node-wise) //////////////////////////////////////////////////////////////////////////////// -struct ParentVisitor { +struct ParentVisitor<'a, 'tcx:'a> { + tcx: &'a ty::ctxt<'tcx>, parents: NodeMap, curparent: ast::NodeId, } -impl<'v> Visitor<'v> for ParentVisitor { +impl<'a, 'tcx, 'v> Visitor<'v> for ParentVisitor<'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 visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.tcx.map.expect_item(item.id)) + } fn visit_item(&mut self, item: &hir::Item) { self.parents.insert(item.id, self.curparent); @@ -99,16 +105,16 @@ impl<'v> Visitor<'v> for ParentVisitor { _ => {} } - visit::walk_item(self, item); + intravisit::walk_item(self, item); self.curparent = prev; } fn visit_foreign_item(&mut self, a: &hir::ForeignItem) { self.parents.insert(a.id, self.curparent); - visit::walk_foreign_item(self, a); + intravisit::walk_foreign_item(self, a); } - fn visit_fn(&mut self, a: visit::FnKind<'v>, b: &'v hir::FnDecl, + fn visit_fn(&mut self, a: intravisit::FnKind<'v>, b: &'v hir::FnDecl, c: &'v hir::Block, d: Span, id: ast::NodeId) { // We already took care of some trait methods above, otherwise things // like impl methods and pub trait methods are parented to the @@ -116,7 +122,7 @@ impl<'v> Visitor<'v> for ParentVisitor { if !self.parents.contains_key(&id) { self.parents.insert(id, self.curparent); } - visit::walk_fn(self, a, b, c, d); + intravisit::walk_fn(self, a, b, c, d); } fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) { @@ -125,7 +131,7 @@ impl<'v> Visitor<'v> for ParentVisitor { if !self.parents.contains_key(&ii.id) { self.parents.insert(ii.id, self.curparent); } - visit::walk_impl_item(self, ii); + intravisit::walk_impl_item(self, ii); } fn visit_variant_data(&mut self, s: &hir::VariantData, _: ast::Name, @@ -141,7 +147,7 @@ impl<'v> Visitor<'v> for ParentVisitor { for field in s.fields() { self.parents.insert(field.node.id, self.curparent); } - visit::walk_struct_def(self, s) + intravisit::walk_struct_def(self, s) } } @@ -216,6 +222,11 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { } impl<'a, 'tcx, 'v> Visitor<'v> 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 visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.tcx.map.expect_item(item.id)) + } fn visit_item(&mut self, item: &hir::Item) { let orig_all_public = self.prev_public; let orig_all_exported = self.prev_exported; @@ -362,7 +373,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { _ => {} } - visit::walk_item(self, item); + intravisit::walk_item(self, item); self.prev_public = orig_all_public; self.prev_exported = orig_all_exported; @@ -375,7 +386,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { // Blocks can have exported and public items, for example impls, but they always // start as non-public and non-exported regardless of publicity of a function, // constant, type, field, etc. in which this block resides - visit::walk_block(self, b); + intravisit::walk_block(self, b); self.prev_public = orig_all_public; self.prev_exported = orig_all_exported; @@ -392,7 +403,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { } } } - visit::walk_mod(self, m) + intravisit::walk_mod(self, m) } fn visit_macro_def(&mut self, md: &'v hir::MacroDef) { @@ -895,9 +906,15 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { } impl<'a, 'tcx, 'v> Visitor<'v> 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 visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.tcx.map.expect_item(item.id)) + } + fn visit_item(&mut self, item: &hir::Item) { let orig_curitem = replace(&mut self.curitem, item.id); - visit::walk_item(self, item); + intravisit::walk_item(self, item); self.curitem = orig_curitem; } @@ -958,7 +975,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { _ => {} } - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); } fn visit_pat(&mut self, pattern: &hir::Pat) { @@ -1004,19 +1021,19 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { _ => {} } - visit::walk_pat(self, pattern); + intravisit::walk_pat(self, pattern); } fn visit_foreign_item(&mut self, fi: &hir::ForeignItem) { self.in_foreign = true; - visit::walk_foreign_item(self, fi); + intravisit::walk_foreign_item(self, fi); self.in_foreign = false; } fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) { if !path.segments.is_empty() { self.check_path(path.span, id, path.segments.last().unwrap().identifier.name); - visit::walk_path(self, path); + intravisit::walk_path(self, path); } } @@ -1029,7 +1046,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { self.tcx.sess.bug("`self` import in an import list with empty prefix"); }; self.check_path(item.span, item.node.id(), name); - visit::walk_path_list_item(self, prefix, item); + intravisit::walk_path_list_item(self, prefix, item); } } @@ -1043,6 +1060,12 @@ struct SanePrivacyVisitor<'a, 'tcx: 'a> { } impl<'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'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 visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.tcx.map.expect_item(item.id)) + } + fn visit_item(&mut self, item: &hir::Item) { self.check_sane_privacy(item); if self.in_block { @@ -1054,13 +1077,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'a, 'tcx> { // Modules turn privacy back on, otherwise we inherit self.in_block = if let hir::ItemMod(..) = item.node { false } else { orig_in_block }; - visit::walk_item(self, item); + intravisit::walk_item(self, item); self.in_block = orig_in_block; } fn visit_block(&mut self, b: &'v hir::Block) { let orig_in_block = replace(&mut self.in_block, true); - visit::walk_block(self, b); + intravisit::walk_block(self, b); self.in_block = orig_in_block; } } @@ -1220,7 +1243,7 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for CheckTypeForPrivatenessVisitor<'a, 'b, 't } } self.at_outer_type = false; - visit::walk_ty(self, ty) + intravisit::walk_ty(self, ty) } // don't want to recurse into [, .. expr] @@ -1228,6 +1251,12 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for CheckTypeForPrivatenessVisitor<'a, 'b, 't } impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'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 visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.tcx.map.expect_item(item.id)) + } + fn visit_item(&mut self, item: &hir::Item) { match item.node { // contents of a private mod can be reexported, so we need @@ -1313,7 +1342,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { not_private_trait && trait_or_some_public_method { - visit::walk_generics(self, g); + intravisit::walk_generics(self, g); match *trait_ref { None => { @@ -1328,10 +1357,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { hir::ImplItemKind::Method(..) if self.item_is_public(&impl_item.id, impl_item.vis) => { - visit::walk_impl_item(self, impl_item) + intravisit::walk_impl_item(self, impl_item) } hir::ImplItemKind::Type(..) => { - visit::walk_impl_item(self, impl_item) + intravisit::walk_impl_item(self, impl_item) } _ => {} } @@ -1351,7 +1380,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { // // Those in 2. are warned via walk_generics and this // call here. - visit::walk_path(self, &tr.path); + intravisit::walk_path(self, &tr.path); // Those in 3. are warned with this call. for impl_item in impl_items { @@ -1370,21 +1399,21 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { hir::ImplItemKind::Const(..) => { if self.item_is_public(&impl_item.id, impl_item.vis) { found_pub_static = true; - visit::walk_impl_item(self, impl_item); + intravisit::walk_impl_item(self, impl_item); } } hir::ImplItemKind::Method(ref sig, _) => { if sig.explicit_self.node == hir::SelfStatic && self.item_is_public(&impl_item.id, impl_item.vis) { found_pub_static = true; - visit::walk_impl_item(self, impl_item); + intravisit::walk_impl_item(self, impl_item); } } _ => {} } } if found_pub_static { - visit::walk_generics(self, g) + intravisit::walk_generics(self, g) } } return @@ -1407,7 +1436,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { // public signatures, i.e. things that we're interested in for // this visitor. debug!("VisiblePrivateTypesVisitor entering item {:?}", item); - visit::walk_item(self, item); + intravisit::walk_item(self, item); } fn visit_generics(&mut self, generics: &hir::Generics) { @@ -1433,7 +1462,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { fn visit_foreign_item(&mut self, item: &hir::ForeignItem) { if self.exported_items.contains(&item.id) { - visit::walk_foreign_item(self, item) + intravisit::walk_foreign_item(self, item) } } @@ -1446,13 +1475,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { "private type in exported type signature"); } } - visit::walk_ty(self, t) + intravisit::walk_ty(self, t) } fn visit_variant(&mut self, v: &hir::Variant, g: &hir::Generics, item_id: ast::NodeId) { if self.exported_items.contains(&v.node.data.id()) { self.in_variant = true; - visit::walk_variant(self, v, g, item_id); + intravisit::walk_variant(self, v, g, item_id); self.in_variant = false; } } @@ -1462,7 +1491,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { hir::NamedField(_, vis) | hir::UnnamedField(vis) => vis }; if vis == hir::Public || self.in_variant { - visit::walk_struct_field(self, s); + intravisit::walk_struct_field(self, s); } } @@ -1489,14 +1518,15 @@ pub fn check_crate(tcx: &ty::ctxt, tcx: tcx, in_block: false, }; - visit::walk_crate(&mut visitor, krate); + intravisit::walk_crate(&mut visitor, krate); // Figure out who everyone's parent is let mut visitor = ParentVisitor { + tcx: tcx, parents: NodeMap(), curparent: ast::DUMMY_NODE_ID, }; - visit::walk_crate(&mut visitor, krate); + intravisit::walk_crate(&mut visitor, krate); // Use the parent map to check the privacy of everything let mut visitor = PrivacyVisitor { @@ -1506,7 +1536,7 @@ pub fn check_crate(tcx: &ty::ctxt, parents: visitor.parents, external_exports: external_exports, }; - visit::walk_crate(&mut visitor, krate); + intravisit::walk_crate(&mut visitor, krate); tcx.sess.abort_if_errors(); @@ -1524,7 +1554,7 @@ pub fn check_crate(tcx: &ty::ctxt, visitor.public_items.insert(ast::CRATE_NODE_ID); loop { let before = (visitor.exported_items.len(), visitor.public_items.len()); - visit::walk_crate(&mut visitor, krate); + intravisit::walk_crate(&mut visitor, krate); let after = (visitor.exported_items.len(), visitor.public_items.len()); if after == before { break @@ -1540,7 +1570,7 @@ pub fn check_crate(tcx: &ty::ctxt, public_items: &public_items, in_variant: false, }; - visit::walk_crate(&mut visitor, krate); + intravisit::walk_crate(&mut visitor, krate); } return (exported_items, public_items); } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 3481f1bfd5203..4ea120724a7ca 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -52,7 +52,7 @@ use rustc_front::hir::StmtDecl; use rustc_front::hir::UnnamedField; use rustc_front::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple}; use rustc_front::hir::Visibility; -use rustc_front::visit::{self, Visitor}; +use rustc_front::intravisit::{self, Visitor}; use std::mem::replace; use std::ops::{Deref, DerefMut}; @@ -111,7 +111,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { builder: self, parent: parent, }; - visit::walk_crate(&mut visitor, krate); + intravisit::walk_crate(&mut visitor, krate); } /// Adds a new child item to the module definition of the parent node and @@ -1051,10 +1051,14 @@ struct BuildReducedGraphVisitor<'a, 'b: 'a, 'tcx: 'b> { } impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { + fn visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.builder.resolver.ast_map.expect_item(item.id)) + } + fn visit_item(&mut self, item: &Item) { let p = self.builder.build_reduced_graph_for_item(item, &self.parent); let old_parent = replace(&mut self.parent, p); - visit::walk_item(self, item); + intravisit::walk_item(self, item); self.parent = old_parent; } @@ -1065,7 +1069,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { fn visit_block(&mut self, block: &Block) { let np = self.builder.build_reduced_graph_for_block(block, &self.parent); let old_parent = replace(&mut self.parent, np); - visit::walk_block(self, block); + intravisit::walk_block(self, block); self.parent = old_parent; } } diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 870990f78607c..439caf20b6b9c 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -29,7 +29,7 @@ use syntax::codemap::{Span, DUMMY_SP}; use rustc_front::hir; use rustc_front::hir::{ViewPathGlob, ViewPathList, ViewPathSimple}; -use rustc_front::visit::{self, Visitor}; +use rustc_front::intravisit::Visitor; struct UnusedImportCheckVisitor<'a, 'b: 'a, 'tcx: 'b> { resolver: &'a mut Resolver<'b, 'tcx>, @@ -118,7 +118,6 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { // because this means that they were generated in some fashion by the // compiler and we don't need to consider them. if item.vis == hir::Public || item.span == DUMMY_SP { - visit::walk_item(self, item); return; } @@ -158,12 +157,10 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { } _ => {} } - - visit::walk_item(self, item); } } pub fn check_crate(resolver: &mut Resolver, krate: &hir::Crate) { let mut visitor = UnusedImportCheckVisitor { resolver: resolver }; - visit::walk_crate(&mut visitor, krate); + krate.visit_all_items(&mut visitor); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0ead5fad92f82..8776ee2d83141 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -76,7 +76,7 @@ use syntax::parse::token::{self, special_names, special_idents}; use syntax::ptr::P; use syntax::codemap::{self, Span, Pos}; -use rustc_front::visit::{self, FnKind, Visitor}; +use rustc_front::intravisit::{self, FnKind, Visitor}; use rustc_front::hir; use rustc_front::hir::{Arm, BindByRef, BindByValue, BindingMode, Block}; use rustc_front::hir::Crate; @@ -541,6 +541,9 @@ enum NameDefinition { } impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { + fn visit_nested_item(&mut self, item: hir::ItemId) { + self.visit_item(self.ast_map.expect_item(item.id)) + } fn visit_item(&mut self, item: &Item) { execute_callback!(hir_map::Node::NodeItem(item), self); self.resolve_item(item); @@ -573,7 +576,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { // error already reported } } - visit::walk_poly_trait_ref(self, tref, m); + intravisit::walk_poly_trait_ref(self, tref, m); } fn visit_variant(&mut self, variant: &hir::Variant, @@ -583,11 +586,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { if let Some(ref dis_expr) = variant.node.disr_expr { // resolve the discriminator expr as a constant self.with_constant_rib(|this| { - this.visit_expr(&**dis_expr); + this.visit_expr(dis_expr); }); } - // `visit::walk_variant` without the discriminant expression. + // `intravisit::walk_variant` without the discriminant expression. self.visit_variant_data(&variant.node.data, variant.node.name, generics, @@ -603,7 +606,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { ForeignItemStatic(..) => NoTypeParameters, }; self.with_type_parameter_rib(type_parameters, |this| { - visit::walk_foreign_item(this, foreign_item); + intravisit::walk_foreign_item(this, foreign_item); }); } fn visit_fn(&mut self, @@ -2047,7 +2050,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_crate(&mut self, krate: &hir::Crate) { debug!("(resolving crate) starting"); - visit::walk_crate(self, krate); + intravisit::walk_crate(self, krate); } fn check_if_primitive_type_name(&self, name: Name, span: Span) { @@ -2071,11 +2074,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.check_if_primitive_type_name(name, item.span); self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind), - |this| visit::walk_item(this, item)); + |this| intravisit::walk_item(this, item)); } ItemFn(_, _, _, _, ref generics, _) => { self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind), - |this| visit::walk_item(this, item)); + |this| intravisit::walk_item(this, item)); } ItemDefaultImpl(_, ref trait_ref) => { @@ -2110,10 +2113,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // expression in a provided default. if default.is_some() { this.with_constant_rib(|this| { - visit::walk_trait_item(this, trait_item) + intravisit::walk_trait_item(this, trait_item) }); } else { - visit::walk_trait_item(this, trait_item) + intravisit::walk_trait_item(this, trait_item) } } hir::MethodTraitItem(ref sig, _) => { @@ -2122,14 +2125,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { FnSpace, MethodRibKind); this.with_type_parameter_rib(type_parameters, |this| { - visit::walk_trait_item(this, trait_item) + intravisit::walk_trait_item(this, trait_item) }); } hir::TypeTraitItem(..) => { this.check_if_primitive_type_name(trait_item.name, trait_item.span); this.with_type_parameter_rib(NoTypeParameters, |this| { - visit::walk_trait_item(this, trait_item) + intravisit::walk_trait_item(this, trait_item) }); } }; @@ -2140,13 +2143,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ItemMod(_) | ItemForeignMod(_) => { self.with_scope(Some(name), |this| { - visit::walk_item(this, item); + intravisit::walk_item(this, item); }); } ItemConst(..) | ItemStatic(..) => { self.with_constant_rib(|this| { - visit::walk_item(this, item); + intravisit::walk_item(this, item); }); } @@ -2283,10 +2286,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { debug!("(resolving function) recorded argument"); } - visit::walk_fn_ret_ty(self, &declaration.output); + intravisit::walk_fn_ret_ty(self, &declaration.output); // Resolve the function body. - self.visit_block(&*block); + self.visit_block(block); debug!("(resolving function) leaving function"); @@ -2347,7 +2350,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } } - visit::walk_generics(self, generics); + intravisit::walk_generics(self, generics); } fn with_current_self_type(&mut self, self_type: &Ty, f: F) -> T @@ -2374,7 +2377,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { new_val = Some((path_res.base_def.def_id(), trait_ref.clone())); new_id = Some(path_res.base_def.def_id()); } - visit::walk_trait_ref(self, trait_ref); + intravisit::walk_trait_ref(self, trait_ref); } let original_trait_ref = replace(&mut self.current_trait_ref, new_val); let result = f(self, new_id); @@ -2427,7 +2430,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { impl_item.span, |n, s| ResolutionError::ConstNotMemberOfTrait(n, s)); this.with_constant_rib(|this| { - visit::walk_impl_item(this, impl_item); + intravisit::walk_impl_item(this, impl_item); }); } hir::ImplItemKind::Method(ref sig, _) => { @@ -2444,7 +2447,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { FnSpace, MethodRibKind); this.with_type_parameter_rib(type_parameters, |this| { - visit::walk_impl_item(this, impl_item); + intravisit::walk_impl_item(this, impl_item); }); } hir::ImplItemKind::Type(ref ty) => { @@ -2583,7 +2586,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let mut found_non_item = false; for statement in &block.stmts { if let hir::StmtDecl(ref declaration, _) = statement.node { - if let hir::DeclItem(ref i) = declaration.node { + if let hir::DeclItem(i) = declaration.node { + let i = self.ast_map.expect_item(i.id); match i.node { ItemExternCrate(_) | ItemUse(_) if found_non_item => { span_err!(self.session, @@ -2602,7 +2606,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } // Descend into the block. - visit::walk_block(self, block); + intravisit::walk_block(self, block); // Move back up. if !self.resolved { @@ -2623,7 +2627,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // `::a::b::c` is resolved by typeck alone. TypecheckRequired => { // Resolve embedded types. - visit::walk_ty(self, ty); + intravisit::walk_ty(self, ty); return; } ResolveAttempt(resolution) => resolution, @@ -2674,7 +2678,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { _ => {} } // Resolve embedded types. - visit::walk_ty(self, ty); + intravisit::walk_ty(self, ty); } fn resolve_pattern(&mut self, @@ -2862,7 +2866,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &path.segments.last().unwrap().identifier.name.as_str()) ); } - visit::walk_path(self, path); + intravisit::walk_path(self, path); } PatQPath(ref qself, ref path) => { @@ -2883,7 +2887,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .name; let traits = self.get_traits_containing_item(const_name); self.trait_map.insert(pattern.id, traits); - visit::walk_pat(self, pattern); + intravisit::walk_pat(self, pattern); return true; } ResolveAttempt(resolution) => resolution, @@ -2915,7 +2919,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .name .as_str())); } - visit::walk_pat(self, pattern); + intravisit::walk_pat(self, pattern); } PatStruct(ref path, _, _) => { @@ -2933,11 +2937,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ); } } - visit::walk_path(self, path); + intravisit::walk_path(self, path); } PatLit(_) | PatRange(..) => { - visit::walk_pat(self, pattern); + intravisit::walk_pat(self, pattern); } _ => { @@ -3665,7 +3669,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let method_name = path.segments.last().unwrap().identifier.name; let traits = self.get_traits_containing_item(method_name); self.trait_map.insert(expr.id, traits); - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); return; } ResolveAttempt(resolution) => resolution, @@ -3777,7 +3781,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); } ExprStruct(ref path, _, _) => { @@ -3797,7 +3801,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); } ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => { @@ -3810,7 +3814,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { rib.bindings.insert(renamed, def_like); } - visit::walk_expr(this, expr); + intravisit::walk_expr(this, expr); }) } @@ -3838,7 +3842,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } _ => { - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); } } } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index c87d9ab7bf049..cd443647ad193 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -100,8 +100,7 @@ use syntax::parse::token::InternedString; use syntax::attr::AttrMetaMethods; use syntax::attr; use rustc_front; -use rustc_front::visit::Visitor; -use rustc_front::visit; +use rustc_front::intravisit::{self, Visitor}; use rustc_front::hir; use syntax::ast; @@ -1300,7 +1299,7 @@ impl<'v> Visitor<'v> for FindNestedReturn { hir::ExprRet(..) => { self.found = true; } - _ => visit::walk_expr(self, e) + _ => intravisit::walk_expr(self, e) } } } @@ -1369,7 +1368,7 @@ fn has_nested_returns(tcx: &ty::ctxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bo Some(hir_map::NodeExpr(ex)) => { if let hir::ExprRet(Some(ref ret_expr)) = ex.node { let mut visitor = FindNestedReturn::new(); - visit::walk_expr(&mut visitor, &**ret_expr); + intravisit::walk_expr(&mut visitor, &**ret_expr); if visitor.found { return true; } @@ -2143,16 +2142,6 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &hir::EnumDef, sp: Span, } } -pub struct TransItemVisitor<'a, 'tcx: 'a> { - pub ccx: &'a CrateContext<'a, 'tcx>, -} - -impl<'a, 'tcx, 'v> Visitor<'v> for TransItemVisitor<'a, 'tcx> { - fn visit_item(&mut self, i: &hir::Item) { - trans_item(self.ccx, i); - } -} - pub fn llvm_linkage_by_name(name: &str) -> Option { // Use the names from src/llvm/docs/LangRef.rst here. Most types are only // applicable to variable declarations and may not really make sense for @@ -2302,11 +2291,6 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) { } } } - - // Be sure to travel more than just one layer deep to catch nested - // items in blocks and such. - let mut v = TransItemVisitor{ ccx: ccx }; - v.visit_block(&**body); } hir::ItemImpl(_, _, ref generics, _, _, ref impl_items) => { meth::trans_impl(ccx, @@ -2315,8 +2299,9 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) { generics, item.id); } - hir::ItemMod(ref m) => { - trans_mod(&ccx.rotate(), m); + hir::ItemMod(_) => { + // modules have no equivalent at runtime, they just affect + // the mangled names of things contained within } hir::ItemEnum(ref enum_definition, ref gens) => { if gens.ty_params.is_empty() { @@ -2325,16 +2310,9 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) { enum_variant_size_lint(ccx, enum_definition, item.span, item.id); } } - hir::ItemConst(_, ref expr) => { - // Recurse on the expression to catch items in blocks - let mut v = TransItemVisitor{ ccx: ccx }; - v.visit_expr(&**expr); + hir::ItemConst(..) => { } hir::ItemStatic(_, m, ref expr) => { - // Recurse on the expression to catch items in blocks - let mut v = TransItemVisitor{ ccx: ccx }; - v.visit_expr(&**expr); - let g = match consts::trans_static(ccx, m, expr, item.id, &item.attrs) { Ok(g) => g, Err(err) => ccx.tcx().sess.span_fatal(expr.span, &err.description()), @@ -2346,30 +2324,11 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) { foreign::trans_foreign_mod(ccx, foreign_mod); } hir::ItemTrait(..) => { - // Inside of this trait definition, we won't be actually translating any - // functions, but the trait still needs to be walked. Otherwise default - // methods with items will not get translated and will cause ICE's when - // metadata time comes around. - let mut v = TransItemVisitor{ ccx: ccx }; - visit::walk_item(&mut v, item); } _ => {/* fall through */ } } } -// Translate a module. Doing this amounts to translating the items in the -// module; there ends up being no artifact (aside from linkage names) of -// separate modules in the compiled program. That's because modules exist -// only as a convenience for humans working with the code, to organize names -// and control visibility. -pub fn trans_mod(ccx: &CrateContext, m: &hir::Mod) { - let _icx = push_ctxt("trans_mod"); - for item in &m.items { - trans_item(ccx, &**item); - } -} - - // only use this for foreign function ABIs and glue, use `register_fn` for Rust functions pub fn register_fn_llvmty(ccx: &CrateContext, sp: Span, @@ -2994,10 +2953,12 @@ pub fn trans_crate<'tcx>(tcx: &ty::ctxt<'tcx>, // First, verify intrinsics. intrinsic::check_intrinsics(&ccx); - // Next, translate the module. + // Next, translate all items. See `TransModVisitor` for + // details on why we walk in this particular way. { let _icx = push_ctxt("text"); - trans_mod(&ccx, &krate.module); + intravisit::walk_mod(&mut TransItemsWithinModVisitor { ccx: &ccx }, &krate.module); + krate.visit_all_items(&mut TransModVisitor { ccx: &ccx }); } } @@ -3100,3 +3061,53 @@ pub fn trans_crate<'tcx>(tcx: &ty::ctxt<'tcx>, no_builtins: no_builtins, } } + +/// We visit all the items in the krate and translate them. We do +/// this in two walks. The first walk just finds module items. It then +/// walks the full contents of those module items and translates all +/// the items within. Note that this entire process is O(n). The +/// reason for this two phased walk is that each module is +/// (potentially) placed into a distinct codegen-unit. This walk also +/// ensures that the immediate contents of each module is processed +/// entirely before we proceed to find more modules, helping to ensure +/// an equitable distribution amongst codegen-units. +pub struct TransModVisitor<'a, 'tcx: 'a> { + pub ccx: &'a CrateContext<'a, 'tcx>, +} + +impl<'a, 'tcx, 'v> Visitor<'v> for TransModVisitor<'a, 'tcx> { + fn visit_item(&mut self, i: &hir::Item) { + match i.node { + hir::ItemMod(_) => { + let item_ccx = self.ccx.rotate(); + intravisit::walk_item(&mut TransItemsWithinModVisitor { ccx: &item_ccx }, i); + } + _ => { } + } + } +} + +/// Translates all the items within a given module. Expects owner to +/// invoke `walk_item` on a module item. Ignores nested modules. +pub struct TransItemsWithinModVisitor<'a, 'tcx: 'a> { + pub ccx: &'a CrateContext<'a, 'tcx>, +} + +impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> { + fn visit_nested_item(&mut self, item_id: hir::ItemId) { + self.visit_item(self.ccx.tcx().map.expect_item(item_id.id)); + } + + fn visit_item(&mut self, i: &hir::Item) { + match i.node { + hir::ItemMod(..) => { + // skip modules, they will be uncovered by the TransModVisitor + } + _ => { + trans_item(self.ccx, i); + intravisit::walk_item(self, i); + } + } + } +} + diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 20388929cbd7a..8449d63015ef7 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -43,7 +43,6 @@ use syntax::attr; use syntax::codemap::DUMMY_SP; use syntax::ptr::P; -use rustc_front::visit; use rustc_front::hir; // drop_glue pointer, size, align. @@ -63,21 +62,12 @@ pub fn trans_impl(ccx: &CrateContext, debug!("trans_impl(name={}, id={})", name, id); - let mut v = TransItemVisitor { ccx: ccx }; - // Both here and below with generic methods, be sure to recurse and look for // items that we need to translate. if !generics.ty_params.is_empty() { - for impl_item in impl_items { - match impl_item.node { - hir::ImplItemKind::Method(..) => { - visit::walk_impl_item(&mut v, impl_item); - } - _ => {} - } - } return; } + for impl_item in impl_items { match impl_item.node { hir::ImplItemKind::Method(ref sig, ref body) => { @@ -94,7 +84,6 @@ pub fn trans_impl(ccx: &CrateContext, if is_origin { OriginalTranslation } else { InlinedCopy }); } } - visit::walk_impl_item(&mut v, impl_item); } _ => {} } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 5c0b35e46b13e..69770cd33b352 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -386,7 +386,7 @@ impl Ord for TraitInfo { /// Retrieve all traits in this crate and any dependent crates. pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { if ccx.all_traits.borrow().is_none() { - use rustc_front::visit; + use rustc_front::intravisit; let mut traits = vec![]; @@ -397,7 +397,7 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { map: &'a hir_map::Map<'tcx>, traits: &'a mut AllTraitsVec, } - impl<'v, 'a, 'tcx> visit::Visitor<'v> for Visitor<'a, 'tcx> { + impl<'v, 'a, 'tcx> intravisit::Visitor<'v> for Visitor<'a, 'tcx> { fn visit_item(&mut self, i: &'v hir::Item) { match i.node { hir::ItemTrait(..) => { @@ -406,13 +406,12 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { } _ => {} } - visit::walk_item(self, i) } } - visit::walk_crate(&mut Visitor { + ccx.tcx.map.krate().visit_all_items(&mut Visitor { map: &ccx.tcx.map, traits: &mut traits - }, ccx.tcx.map.krate()); + }); // Cross-crate: let mut external_mods = FnvHashSet(); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5ed6b62e8c3ef..a635c1b047da3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -124,7 +124,7 @@ use syntax::owned_slice::OwnedSlice; use syntax::parse::token::{self, InternedString}; use syntax::ptr::P; -use rustc_front::visit::{self, Visitor}; +use rustc_front::intravisit::{self, Visitor}; use rustc_front::hir; use rustc_front::hir::Visibility; use rustc_front::hir::{Item, ItemImpl}; @@ -363,7 +363,7 @@ struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { fn visit_item(&mut self, i: &'tcx hir::Item) { check_item_type(self.ccx, i); - visit::walk_item(self, i); + intravisit::walk_item(self, i); } fn visit_ty(&mut self, t: &'tcx hir::Ty) { @@ -371,22 +371,16 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { hir::TyFixedLengthVec(_, ref expr) => { check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize); } - hir::TyBareFn(ref function_declaration) => { - visit::walk_fn_decl_nopat(self, &function_declaration.decl); - walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes); - return - } _ => {} } - visit::walk_ty(self, t); + intravisit::walk_ty(self, t); } } impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { fn visit_item(&mut self, i: &'tcx hir::Item) { check_item_body(self.ccx, i); - visit::walk_item(self, i); } } @@ -398,7 +392,7 @@ pub fn check_wf_old(ccx: &CrateCtxt) { // comes, we run the new code and issue warnings. let krate = ccx.tcx.map.krate(); let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx); - visit::walk_crate(&mut visit, krate); + krate.visit_all_items(&mut visit); // If types are not well-formed, it leads to all manner of errors // downstream, so stop reporting errors at this point. @@ -408,7 +402,7 @@ pub fn check_wf_old(ccx: &CrateCtxt) { pub fn check_wf_new(ccx: &CrateCtxt) { let krate = ccx.tcx.map.krate(); let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx); - visit::walk_crate(&mut visit, krate); + krate.visit_all_items(&mut visit); // If types are not well-formed, it leads to all manner of errors // downstream, so stop reporting errors at this point. @@ -418,14 +412,14 @@ pub fn check_wf_new(ccx: &CrateCtxt) { pub fn check_item_types(ccx: &CrateCtxt) { let krate = ccx.tcx.map.krate(); let mut visit = CheckItemTypesVisitor { ccx: ccx }; - visit::walk_crate(&mut visit, krate); + krate.visit_all_items(&mut visit); ccx.tcx.sess.abort_if_errors(); } pub fn check_item_bodies(ccx: &CrateCtxt) { let krate = ccx.tcx.map.krate(); let mut visit = CheckItemBodiesVisitor { ccx: ccx }; - visit::walk_crate(&mut visit, krate); + krate.visit_all_items(&mut visit); ccx.tcx.sess.abort_if_errors(); } @@ -523,7 +517,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { local.pat, self.fcx.infcx().ty_to_string( self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone())); - visit::walk_local(self, local); + intravisit::walk_local(self, local); } // Add pattern bindings. @@ -542,14 +536,14 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { var_ty); } } - visit::walk_pat(self, p); + intravisit::walk_pat(self, p); } fn visit_block(&mut self, b: &'tcx hir::Block) { // non-obvious: the `blk` variable maps to region lb, so // we have to keep this up-to-date. This // is... unfortunate. It'd be nice to not need this. - visit::walk_block(self, b); + intravisit::walk_block(self, b); } // Since an expr occurs as part of the type fixed size arrays we @@ -561,18 +555,16 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize); } hir::TyBareFn(ref function_declaration) => { - visit::walk_fn_decl_nopat(self, &function_declaration.decl); + intravisit::walk_fn_decl_nopat(self, &function_declaration.decl); walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes); } - _ => visit::walk_ty(self, t) + _ => intravisit::walk_ty(self, t) } } - // Don't descend into fns and items - fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx hir::FnDecl, + // Don't descend into the bodies of nested closures + fn visit_fn(&mut self, _: intravisit::FnKind<'tcx>, _: &'tcx hir::FnDecl, _: &'tcx hir::Block, _: Span, _: ast::NodeId) { } - fn visit_item(&mut self, _: &hir::Item) { } - } /// Helper used by check_bare_fn and check_expr_fn. Does the grungy work of checking a function diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 3cdc9b559446e..095dded777022 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -102,8 +102,7 @@ use std::mem; use std::rc::Rc; use syntax::ast; use syntax::codemap::Span; -use rustc_front::visit; -use rustc_front::visit::Visitor; +use rustc_front::intravisit::{self, Visitor}; use rustc_front::hir; use rustc_front::util as hir_util; @@ -496,13 +495,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Rcx<'a, 'tcx> { // hierarchy, and in particular the relationships between free // regions, until regionck, as described in #3238. - fn visit_fn(&mut self, _fk: visit::FnKind<'v>, fd: &'v hir::FnDecl, + fn visit_fn(&mut self, _fk: intravisit::FnKind<'v>, fd: &'v hir::FnDecl, b: &'v hir::Block, span: Span, id: ast::NodeId) { self.visit_fn_body(id, fd, b, span) } - fn visit_item(&mut self, i: &hir::Item) { visit_item(self, i); } - fn visit_expr(&mut self, ex: &hir::Expr) { visit_expr(self, ex); } //visit_pat: visit_pat, // (..) see above @@ -514,12 +511,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Rcx<'a, 'tcx> { fn visit_block(&mut self, b: &hir::Block) { visit_block(self, b); } } -fn visit_item(_rcx: &mut Rcx, _item: &hir::Item) { - // Ignore items -} - fn visit_block(rcx: &mut Rcx, b: &hir::Block) { - visit::walk_block(rcx, b); + intravisit::walk_block(rcx, b); } fn visit_arm(rcx: &mut Rcx, arm: &hir::Arm) { @@ -528,14 +521,14 @@ fn visit_arm(rcx: &mut Rcx, arm: &hir::Arm) { constrain_bindings_in_pat(&**p, rcx); } - visit::walk_arm(rcx, arm); + intravisit::walk_arm(rcx, arm); } fn visit_local(rcx: &mut Rcx, l: &hir::Local) { // see above constrain_bindings_in_pat(&*l.pat, rcx); link_local(rcx, l); - visit::walk_local(rcx, l); + intravisit::walk_local(rcx, l); } fn constrain_bindings_in_pat(pat: &hir::Pat, rcx: &mut Rcx) { @@ -700,14 +693,14 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { args.iter().map(|e| &**e), false); } - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprMethodCall(_, _, ref args) => { constrain_call(rcx, expr, Some(&*args[0]), args[1..].iter().map(|e| &**e), false); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprAssignOp(_, ref lhs, ref rhs) => { @@ -716,14 +709,14 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { Some(&**rhs).into_iter(), false); } - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprIndex(ref lhs, ref rhs) if has_method_map => { constrain_call(rcx, expr, Some(&**lhs), Some(&**rhs).into_iter(), true); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); }, hir::ExprBinary(op, ref lhs, ref rhs) if has_method_map => { @@ -736,7 +729,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { constrain_call(rcx, expr, Some(&**lhs), Some(&**rhs).into_iter(), implicitly_ref_args); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprBinary(_, ref lhs, ref rhs) => { @@ -750,7 +743,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { ty, expr_region); } - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprUnary(op, ref lhs) if has_method_map => { @@ -760,7 +753,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { constrain_call(rcx, expr, Some(&**lhs), None::.iter(), implicitly_ref_args); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprUnary(hir::UnDeref, ref base) => { @@ -781,7 +774,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { rcx, expr.span, expr_region, *r_ptr); } - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprIndex(ref vec_expr, _) => { @@ -789,7 +782,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { let vec_type = rcx.resolve_expr_type_adjusted(&**vec_expr); constrain_index(rcx, expr, vec_type); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprCast(ref source, _) => { @@ -797,7 +790,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { // instance. If so, we have to be sure that the type of // the source obeys the trait's region bound. constrain_cast(rcx, expr, &**source); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprAddrOf(m, ref base) => { @@ -812,13 +805,13 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { // FIXME(#6268) nested method calls requires that this rule change let ty0 = rcx.resolve_node_type(expr.id); type_must_outlive(rcx, infer::AddrOf(expr.span), ty0, expr_region); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprMatch(ref discr, ref arms, _) => { link_match(rcx, &**discr, &arms[..]); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } hir::ExprClosure(_, _, ref body) => { @@ -827,7 +820,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { hir::ExprLoop(ref body, _) => { let repeating_scope = rcx.set_repeating_scope(body.id); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); rcx.set_repeating_scope(repeating_scope); } @@ -842,7 +835,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { } _ => { - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); } } } @@ -897,7 +890,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, expr: &hir::Expr, body: &hir::Block) { let repeating_scope = rcx.set_repeating_scope(body.id); - visit::walk_expr(rcx, expr); + intravisit::walk_expr(rcx, expr); rcx.set_repeating_scope(repeating_scope); } diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index d4a2fe872652d..0b77935771e44 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -52,7 +52,7 @@ use std::collections::HashSet; use syntax::ast; use syntax::codemap::Span; use rustc_front::hir; -use rustc_front::visit::{self, Visitor}; +use rustc_front::intravisit::{self, Visitor}; /////////////////////////////////////////////////////////////////////////// // PUBLIC ENTRY POINTS @@ -105,11 +105,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for SeedBorrowKind<'a, 'tcx> { _ => { } } - visit::walk_expr(self, expr); + intravisit::walk_expr(self, expr); } - - // Skip all items; they aren't in the same context. - fn visit_item(&mut self, _: &'v hir::Item) { } } impl<'a,'tcx> SeedBorrowKind<'a,'tcx> { @@ -510,18 +507,15 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { impl<'a, 'tcx, 'v> Visitor<'v> for AdjustBorrowKind<'a, 'tcx> { fn visit_fn(&mut self, - fn_kind: visit::FnKind<'v>, + fn_kind: intravisit::FnKind<'v>, decl: &'v hir::FnDecl, body: &'v hir::Block, span: Span, id: ast::NodeId) { - visit::walk_fn(self, fn_kind, decl, body, span); + intravisit::walk_fn(self, fn_kind, decl, body, span); self.analyze_closure(id, span, decl, body); } - - // Skip all items; they aren't in the same context. - fn visit_item(&mut self, _: &'v hir::Item) { } } impl<'a,'tcx> euv::Delegate<'tcx> for AdjustBorrowKind<'a,'tcx> { diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index e41b4de7ba1fd..3daf5003b97e0 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -24,7 +24,7 @@ use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; use syntax::parse::token::special_idents; -use rustc_front::visit::{self, Visitor, FnKind}; +use rustc_front::intravisit::{self, Visitor, FnKind}; use rustc_front::hir; pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> { @@ -423,7 +423,7 @@ fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>, impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { fn visit_item(&mut self, i: &hir::Item) { self.check_item_well_formed(i); - visit::walk_item(self, i); + intravisit::walk_item(self, i); } fn visit_fn(&mut self, @@ -440,7 +440,7 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { } } } - visit::walk_fn(self, fk, fd, b, span) + intravisit::walk_fn(self, fk, fd, b, span) } fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) { @@ -460,7 +460,7 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { } } - visit::walk_trait_item(self, trait_item) + intravisit::walk_trait_item(self, trait_item) } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index ab091472d2ca3..bfbf8fff4f537 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -25,8 +25,7 @@ use syntax::ast; use syntax::codemap::{Span}; use syntax::parse::token::{special_idents}; use syntax::ptr::P; -use rustc_front::visit; -use rustc_front::visit::Visitor; +use rustc_front::intravisit::{self, Visitor}; use rustc_front::hir; pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> { @@ -492,19 +491,19 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { fn visit_item(&mut self, i: &hir::Item) { debug!("visit_item: {:?}", i); self.check_item_well_formed(i); - visit::walk_item(self, i); + intravisit::walk_item(self, i); } fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) { debug!("visit_trait_item: {:?}", trait_item); self.check_trait_or_impl_item(trait_item.id, trait_item.span); - visit::walk_trait_item(self, trait_item) + intravisit::walk_trait_item(self, trait_item) } fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) { debug!("visit_impl_item: {:?}", impl_item); self.check_trait_or_impl_item(impl_item.id, impl_item.span); - visit::walk_impl_item(self, impl_item) + intravisit::walk_impl_item(self, impl_item) } } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 5b1fafe09fac9..984f227cebe79 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -29,8 +29,7 @@ use std::cell::Cell; use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; use rustc_front::print::pprust::pat_to_string; -use rustc_front::visit; -use rustc_front::visit::Visitor; +use rustc_front::intravisit::{self, Visitor}; use rustc_front::util as hir_util; use rustc_front::hir; @@ -153,17 +152,13 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // traffic in node-ids or update tables in the type context etc. impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { - fn visit_item(&mut self, _: &hir::Item) { - // Ignore items - } - fn visit_stmt(&mut self, s: &hir::Stmt) { if self.fcx.writeback_errors.get() { return; } self.visit_node_id(ResolvingExpr(s.span), hir_util::stmt_id(s)); - visit::walk_stmt(self, s); + intravisit::walk_stmt(self, s); } fn visit_expr(&mut self, e: &hir::Expr) { @@ -183,7 +178,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { } } - visit::walk_expr(self, e); + intravisit::walk_expr(self, e); } fn visit_block(&mut self, b: &hir::Block) { @@ -192,7 +187,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { } self.visit_node_id(ResolvingExpr(b.span), b.id); - visit::walk_block(self, b); + intravisit::walk_block(self, b); } fn visit_pat(&mut self, p: &hir::Pat) { @@ -207,7 +202,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { p.id, self.tcx().node_id_to_type(p.id)); - visit::walk_pat(self, p); + intravisit::walk_pat(self, p); } fn visit_local(&mut self, l: &hir::Local) { @@ -218,7 +213,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { let var_ty = self.fcx.local_ty(l.span, l.id); let var_ty = self.resolve(&var_ty, ResolvingLocal(l.span)); write_ty_to_tcx(self.tcx(), l.id, var_ty); - visit::walk_local(self, l); + intravisit::walk_local(self, l); } fn visit_ty(&mut self, t: &hir::Ty) { @@ -228,10 +223,10 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { write_ty_to_tcx(self.tcx(), count_expr.id, self.tcx().types.usize); } hir::TyBareFn(ref function_declaration) => { - visit::walk_fn_decl_nopat(self, &function_declaration.decl); + intravisit::walk_fn_decl_nopat(self, &function_declaration.decl); walk_list!(self, visit_lifetime_def, &function_declaration.lifetimes); } - _ => visit::walk_ty(self, t) + _ => intravisit::walk_ty(self, t) } } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 6b2994d9dc06a..b3614210eefb6 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -41,7 +41,7 @@ use syntax::parse::token; use util::nodemap::{DefIdMap, FnvHashMap}; use rustc::front::map as hir_map; use rustc::front::map::NodeItem; -use rustc_front::visit; +use rustc_front::intravisit; use rustc_front::hir::{Item, ItemImpl,Crate}; use rustc_front::hir; @@ -96,13 +96,11 @@ struct CoherenceCheckVisitor<'a, 'tcx: 'a> { cc: &'a CoherenceChecker<'a, 'tcx> } -impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> { +impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &Item) { if let ItemImpl(..) = item.node { self.cc.check_implementation(item) } - - visit::walk_item(self, item); } } @@ -111,8 +109,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // Check implementations and traits. This populates the tables // containing the inherent methods and extension methods. It also // builds up the trait inheritance table. - let mut visitor = CoherenceCheckVisitor { cc: self }; - visit::walk_crate(&mut visitor, krate); + krate.visit_all_items(&mut CoherenceCheckVisitor { cc: self }); // Copy over the inherent impls we gathered up during the walk into // the tcx. diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index f796f7fe9f9bd..8eeafb9b432a8 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -17,13 +17,13 @@ use middle::traits; use middle::ty; use syntax::ast; use syntax::codemap::Span; -use rustc_front::visit; +use rustc_front::intravisit; use rustc_front::hir; use rustc_front::hir::{Item, ItemImpl}; pub fn check(tcx: &ty::ctxt) { let mut orphan = OrphanChecker { tcx: tcx }; - visit::walk_crate(&mut orphan, tcx.map.krate()); + tcx.map.krate().visit_all_items(&mut orphan); } struct OrphanChecker<'cx, 'tcx:'cx> { @@ -354,9 +354,8 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { } } -impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> { +impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OrphanChecker<'cx, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { self.check_item(item); - visit::walk_item(self, item); } } diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 54dfd01c92bcb..e91702e64ba9f 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -19,7 +19,7 @@ use middle::infer::{self, new_infer_ctxt}; use syntax::ast; use syntax::codemap::Span; use rustc_front::hir; -use rustc_front::visit; +use rustc_front::intravisit; use util::nodemap::DefIdMap; pub fn check(tcx: &ty::ctxt) { @@ -28,7 +28,7 @@ pub fn check(tcx: &ty::ctxt) { // this secondary walk specifically checks for some other cases, // like defaulted traits, for which additional overlap rules exist - visit::walk_crate(&mut overlap, tcx.map.krate()); + tcx.map.krate().visit_all_items(&mut overlap); } struct OverlapChecker<'cx, 'tcx:'cx> { @@ -169,7 +169,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { } -impl<'cx, 'tcx,'v> visit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { +impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { fn visit_item(&mut self, item: &'v hir::Item) { match item.node { hir::ItemDefaultImpl(_, _) => { @@ -226,6 +226,5 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { _ => { } } - visit::walk_item(self, item); } } diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index f7b10b9001340..40b38ad88394b 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -12,13 +12,13 @@ //! crate or pertains to a type defined in this crate. use middle::ty; -use rustc_front::visit; +use rustc_front::intravisit; use rustc_front::hir; use rustc_front::hir::{Item, ItemImpl}; pub fn check(tcx: &ty::ctxt) { let mut orphan = UnsafetyChecker { tcx: tcx }; - visit::walk_crate(&mut orphan, tcx.map.krate()); + tcx.map.krate().visit_all_items(&mut orphan); } struct UnsafetyChecker<'cx, 'tcx:'cx> { @@ -76,7 +76,7 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { } } -impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> { +impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> { fn visit_item(&mut self, item: &'v hir::Item) { match item.node { hir::ItemDefaultImpl(unsafety, _) => { @@ -87,7 +87,5 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> { } _ => { } } - - visit::walk_item(self, item); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 80f9018299245..efda06d8cf619 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -98,7 +98,7 @@ use syntax::codemap::Span; use syntax::parse::token::special_idents; use syntax::ptr::P; use rustc_front::hir; -use rustc_front::visit; +use rustc_front::intravisit; use rustc_front::print::pprust; /////////////////////////////////////////////////////////////////////////// @@ -108,10 +108,10 @@ pub fn collect_item_types(tcx: &ty::ctxt) { let ccx = &CrateCtxt { tcx: tcx, stack: RefCell::new(Vec::new()) }; let mut visitor = CollectTraitDefVisitor{ ccx: ccx }; - visit::walk_crate(&mut visitor, ccx.tcx.map.krate()); + ccx.tcx.map.krate().visit_all_items(&mut visitor); let mut visitor = CollectItemTypesVisitor{ ccx: ccx }; - visit::walk_crate(&mut visitor, ccx.tcx.map.krate()); + ccx.tcx.map.krate().visit_all_items(&mut visitor); } /////////////////////////////////////////////////////////////////////////// @@ -157,7 +157,7 @@ struct CollectTraitDefVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } -impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> { +impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> { fn visit_item(&mut self, i: &hir::Item) { match i.node { hir::ItemTrait(..) => { @@ -166,8 +166,6 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> { } _ => { } } - - visit::walk_item(self, i); } } @@ -178,14 +176,14 @@ struct CollectItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } -impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> { +impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> { fn visit_item(&mut self, i: &hir::Item) { convert_item(self.ccx, i); - visit::walk_item(self, i); + intravisit::walk_item(self, i); } fn visit_foreign_item(&mut self, i: &hir::ForeignItem) { convert_foreign_item(self.ccx, i); - visit::walk_foreign_item(self, i); + intravisit::walk_foreign_item(self, i); } } diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index 8152e685d8d83..c9035bdff719d 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -276,8 +276,7 @@ use std::fmt; use std::rc::Rc; use syntax::ast; use rustc_front::hir; -use rustc_front::visit; -use rustc_front::visit::Visitor; +use rustc_front::intravisit::Visitor; use util::nodemap::NodeMap; pub fn infer_variance(tcx: &ty::ctxt) { @@ -383,7 +382,7 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, }) }; - visit::walk_crate(&mut terms_cx, krate); + krate.visit_all_items(&mut terms_cx); terms_cx } @@ -531,7 +530,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> { // constrained to be invariant. See `visit_item` in // the impl for `ConstraintContext` below. self.add_inferreds_for_item(item.id, true, generics); - visit::walk_item(self, item); } hir::ItemExternCrate(_) | @@ -544,7 +542,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> { hir::ItemMod(..) | hir::ItemForeignMod(..) | hir::ItemTy(..) => { - visit::walk_item(self, item); } } } @@ -591,7 +588,7 @@ fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>, bivariant: bivariant, constraints: Vec::new(), }; - visit::walk_crate(&mut constraint_cx, krate); + krate.visit_all_items(&mut constraint_cx); constraint_cx } @@ -637,8 +634,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { hir::ItemDefaultImpl(..) => { } } - - visit::walk_item(self, item); } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index b6c93bf00af5f..36ef110fba07a 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -157,8 +157,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om.vis = vis; om.stab = self.stability(id); om.id = id; - for i in &m.items { - self.visit_item(&**i, None, &mut om); + for i in &m.item_ids { + let item = self.cx.map.expect_item(i.id); + self.visit_item(item, None, &mut om); } om } @@ -224,8 +225,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let prev = mem::replace(&mut self.inlining_from_glob, true); match it.node { hir::ItemMod(ref m) => { - for i in &m.items { - self.visit_item(&**i, None, om); + for i in &m.item_ids { + let i = self.cx.map.expect_item(i.id); + self.visit_item(i, None, om); } } hir::ItemEnum(..) => {} diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index f1c88232fc45a..44334762d9022 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -289,7 +289,6 @@ pub trait IdVisitingOperation { pub struct IdVisitor<'a, O:'a> { pub operation: &'a mut O, - pub pass_through_items: bool, pub visited_outermost: bool, } @@ -319,12 +318,10 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { } fn visit_item(&mut self, item: &Item) { - if !self.pass_through_items { - if self.visited_outermost { - return - } else { - self.visited_outermost = true - } + if self.visited_outermost { + return + } else { + self.visited_outermost = true } self.operation.visit_id(item.id); @@ -390,12 +387,10 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { block: &'v Block, span: Span, node_id: NodeId) { - if !self.pass_through_items { - match function_kind { - FnKind::Method(..) if self.visited_outermost => return, - FnKind::Method(..) => self.visited_outermost = true, - _ => {} - } + match function_kind { + FnKind::Method(..) if self.visited_outermost => return, + FnKind::Method(..) => self.visited_outermost = true, + _ => {} } self.operation.visit_id(node_id); @@ -420,10 +415,8 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { block, span); - if !self.pass_through_items { - if let FnKind::Method(..) = function_kind { - self.visited_outermost = false; - } + if let FnKind::Method(..) = function_kind { + self.visited_outermost = false; } } @@ -497,7 +490,6 @@ pub fn compute_id_range_for_fn_body(fk: FnKind, let mut visitor = IdRangeComputingVisitor::new(); let mut id_visitor = IdVisitor { operation: &mut visitor, - pass_through_items: false, visited_outermost: false, }; id_visitor.visit_fn(fk, decl, body, sp, id); diff --git a/src/test/compile-fail/issue-22638.rs b/src/test/compile-fail/issue-22638.rs index 3f4f2ced28320..e8c17ca0b362b 100644 --- a/src/test/compile-fail/issue-22638.rs +++ b/src/test/compile-fail/issue-22638.rs @@ -10,6 +10,8 @@ #![allow(unused)] +#![recursion_limit = "32"] + #[derive(Clone)] struct A (B); diff --git a/src/test/run-make/graphviz-flowgraph/f18.dot-expected.dot b/src/test/run-make/graphviz-flowgraph/f18.dot-expected.dot index 78120e9009e69..8ea4256133296 100644 --- a/src/test/run-make/graphviz-flowgraph/f18.dot-expected.dot +++ b/src/test/run-make/graphviz-flowgraph/f18.dot-expected.dot @@ -1,14 +1,14 @@ digraph block { N0[label="entry"]; N1[label="exit"]; - N2[label="stmt fn inner(x: isize) -> isize { x + x }"]; + N2[label="stmt "]; N3[label="expr inner"]; N4[label="expr inner"]; N5[label="expr 18"]; N6[label="expr inner(18)"]; N7[label="expr inner(inner(18))"]; N8[label="stmt inner(inner(18));"]; - N9[label="block {\l fn inner(x: isize) -> isize { x + x }\l inner(inner(18));\l}\l"]; + N9[label="block { inner(inner(18)); }"]; N0 -> N2; N2 -> N3; N3 -> N4; diff --git a/src/test/run-make/graphviz-flowgraph/f19.dot-expected.dot b/src/test/run-make/graphviz-flowgraph/f19.dot-expected.dot index 4752eac3e2856..bc0ca08d42257 100644 --- a/src/test/run-make/graphviz-flowgraph/f19.dot-expected.dot +++ b/src/test/run-make/graphviz-flowgraph/f19.dot-expected.dot @@ -1,8 +1,8 @@ digraph block { N0[label="entry"]; N1[label="exit"]; - N2[label="stmt struct S19 {\l x: isize,\l}\l"]; - N3[label="stmt impl S19 {\l fn inner(self) -> S19 { S19{x: self.x + self.x,} }\l}\l"]; + N2[label="stmt "]; + N3[label="stmt "]; N4[label="expr 19"]; N5[label="expr S19{x: 19,}"]; N6[label="local s"]; @@ -11,7 +11,7 @@ digraph block { N9[label="expr s.inner()"]; N10[label="expr s.inner().inner()"]; N11[label="stmt s.inner().inner();"]; - N12[label="block {\l struct S19 {\l x: isize,\l }\l impl S19 {\l fn inner(self) -> S19 { S19{x: self.x + self.x,} }\l }\l let s = S19{x: 19,};\l s.inner().inner();\l}\l"]; + N12[label="block { let s = S19{x: 19,}; s.inner().inner(); }"]; N0 -> N2; N2 -> N3; N3 -> N4;