From c99b73a767a38d5b97214b7dbf6ee3c08ac782fd Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 7 Apr 2016 18:16:12 +1200 Subject: [PATCH 1/9] Trivial refactoring --- src/librustc_driver/driver.rs | 14 +++++++------- src/librustc_metadata/creader.rs | 17 ++++++++--------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index de1a740e0bba4..9c444fca9a10e 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -766,12 +766,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, "external crate/lib resolution", || LocalCrateReader::new(sess, cstore, &hir_map, name).read_crates()); - let lang_items = time(time_passes, "language item collection", || { - sess.track_errors(|| { - middle::lang_items::collect_language_items(&sess, &hir_map) - }) - })?; - let resolve::CrateMap { def_map, freevars, @@ -779,9 +773,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, trait_map, glob_map, } = time(time_passes, - "resolution", + "name resolution", || resolve::resolve_crate(sess, &hir_map, make_glob_map)); + let lang_items = time(time_passes, "language item collection", || { + sess.track_errors(|| { + middle::lang_items::collect_language_items(&sess, &hir_map) + }) + })?; + let mut analysis = ty::CrateAnalysis { export_map: export_map, access_levels: AccessLevels::default(), diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index df9072835b9e8..8ec238f4b248f 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -813,9 +813,8 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { fn process_crate(&self, c: &hir::Crate) { for a in c.attrs.iter().filter(|m| m.name() == "link_args") { - match a.value_str() { - Some(ref linkarg) => self.cstore.add_used_link_args(&linkarg), - None => { /* fallthrough */ } + if let Some(ref linkarg) = a.value_str() { + self.cstore.add_used_link_args(&linkarg); } } } @@ -830,12 +829,12 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { match self.creader.extract_crate_info_hir(i) { Some(info) => { let (cnum, _, _) = self.creader.resolve_crate(&None, - &info.ident, - &info.name, - None, - i.span, - PathKind::Crate, - true); + &info.ident, + &info.name, + None, + i.span, + PathKind::Crate, + true); let def_id = self.ast_map.local_def_id(i.id); let len = self.ast_map.def_path(def_id).data.len(); From f61b40446777f9ef9b32c19d8df24ded855fd082 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 11:55:34 +1200 Subject: [PATCH 2/9] Split up NodeCollector so that defs are collected separately from nodes for the HIR map. --- src/librustc/hir/map/collector.rs | 323 ++++++++++++++++++++---------- src/librustc/hir/map/mod.rs | 38 ++-- src/librustc_driver/driver.rs | 37 ++-- 3 files changed, 263 insertions(+), 135 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 95f9e8eaac2e8..7f6a587fade24 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -19,25 +19,28 @@ use std::iter::repeat; use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; use syntax::codemap::Span; -/// A Visitor that walks over an AST and collects Node's into an AST -/// Map. +/// A Visitor that walks over the HIR and collects Node's into a HIR 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(krate: &'ast Crate) -> NodeCollector<'ast> { - let mut collector = NodeCollector { +pub struct DefCollector<'ast> { + pub krate: &'ast Crate, + pub map: &'ast [MapEntry<'ast>], + pub definitions: Definitions, + pub parent_def: Option, +} + +impl<'ast> DefCollector<'ast> { + pub fn root(krate: &'ast Crate, map: &'ast [MapEntry<'ast>]) -> DefCollector<'ast> { + let mut collector = DefCollector { krate: krate, - map: vec![], + map: map, definitions: Definitions::new(), - parent_node: CRATE_NODE_ID, + parent_def: None, }; - collector.insert_entry(CRATE_NODE_ID, RootCrate); - let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); assert_eq!(result, CRATE_DEF_INDEX); @@ -47,17 +50,16 @@ impl<'ast> NodeCollector<'ast> { } pub fn extend(krate: &'ast Crate, - parent: &'ast InlinedItem, parent_node: NodeId, parent_def_path: DefPath, parent_def_id: DefId, - map: Vec>, + map: &'ast [MapEntry<'ast>], definitions: Definitions) - -> NodeCollector<'ast> { - let mut collector = NodeCollector { + -> DefCollector<'ast> { + let mut collector = DefCollector { krate: krate, map: map, - parent_node: parent_node, + parent_def: None, definitions: definitions, }; @@ -67,21 +69,14 @@ impl<'ast> NodeCollector<'ast> { def_id: parent_def_id, }); - collector.insert_entry(parent_node, RootInlinedParent(parent)); - collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); + let def = collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); + collector.parent_def = Some(def); collector } fn parent_def(&self) -> Option { - let mut parent_node = Some(self.parent_node); - while let Some(p) = parent_node { - if let Some(q) = self.definitions.opt_def_index(p) { - return Some(q); - } - parent_node = self.map[p as usize].parent_node(); - } - None + self.parent_def } fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex { @@ -97,28 +92,9 @@ impl<'ast> NodeCollector<'ast> { -> DefIndex { self.definitions.create_def_with_parent(parent, node_id, data) } - - fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) { - debug!("ast_map: {:?} => {:?}", id, entry); - let len = self.map.len(); - if id as usize >= len { - self.map.extend(repeat(NotPresent).take(id as usize - len + 1)); - } - self.map[id as usize] = entry; - } - - fn insert_def(&mut self, id: NodeId, node: Node<'ast>, data: DefPathData) -> DefIndex { - self.insert(id, node); - self.create_def(id, data) - } - - fn insert(&mut self, id: NodeId, node: Node<'ast>) { - let entry = MapEntry::from_node(self.parent_node, node); - self.insert_entry(id, entry); - } } -impl<'ast> Visitor<'ast> for NodeCollector<'ast> { +impl<'ast> Visitor<'ast> for DefCollector<'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. @@ -146,18 +122,16 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { DefPathData::Misc, }; - self.insert_def(i.id, NodeItem(i), def_data); + let def = self.create_def(i.id, def_data); - let parent_node = self.parent_node; - self.parent_node = i.id; + let parent_def = self.parent_def; + self.parent_def = Some(def); match i.node { - ItemImpl(..) => {} ItemEnum(ref enum_definition, _) => { for v in &enum_definition.variants { let variant_def_index = - self.insert_def(v.node.data.id(), - NodeVariant(v), + self.create_def(v.node.data.id(), DefPathData::EnumVariant(v.node.name)); for field in v.node.data.fields() { @@ -168,13 +142,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } } } - ItemForeignMod(..) => { - } ItemStruct(ref struct_def, _) => { // If this is a tuple-like struct, register the constructor. if !struct_def.is_struct() { - self.insert_def(struct_def.id(), - NodeStructCtor(struct_def), + self.create_def(struct_def.id(), DefPathData::StructCtor); } @@ -182,44 +153,24 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.create_def(field.id, DefPathData::Field(field.name)); } } - ItemTrait(_, _, ref bounds, _) => { - for b in bounds.iter() { - if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { - self.insert(t.trait_ref.ref_id, NodeItem(i)); - } - } - } - ItemUse(ref view_path) => { - match view_path.node { - ViewPathList(_, ref paths) => { - for path in paths { - self.insert(path.node.id(), NodeItem(i)); - } - } - _ => () - } - } _ => {} } intravisit::walk_item(self, i); - self.parent_node = parent_node; + self.parent_def = parent_def; } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { - self.insert_def(foreign_item.id, - NodeForeignItem(foreign_item), - DefPathData::ValueNs(foreign_item.name)); + let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); - let parent_node = self.parent_node; - self.parent_node = foreign_item.id; + let parent_def = self.parent_def; + self.parent_def = Some(def); intravisit::walk_foreign_item(self, foreign_item); - self.parent_node = parent_node; + self.parent_def = parent_def; } fn visit_generics(&mut self, generics: &'ast Generics) { for ty_param in generics.ty_params.iter() { - self.insert_def(ty_param.id, - NodeTyParam(ty_param), + self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.name)); } @@ -232,11 +183,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { TypeTraitItem(..) => DefPathData::TypeNs(ti.name), }; - self.insert(ti.id, NodeTraitItem(ti)); - self.create_def(ti.id, def_data); + let def = self.create_def(ti.id, def_data); - let parent_node = self.parent_node; - self.parent_node = ti.id; + let parent_def = self.parent_def; + self.parent_def = Some(def); match ti.node { ConstTraitItem(_, Some(ref expr)) => { @@ -247,7 +197,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { intravisit::walk_trait_item(self, ti); - self.parent_node = parent_node; + self.parent_def = parent_def; } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { @@ -256,10 +206,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), }; - self.insert_def(ii.id, NodeImplItem(ii), def_data); + let def = self.create_def(ii.id, def_data); - let parent_node = self.parent_node; - self.parent_node = ii.id; + let parent_def = self.parent_def; + self.parent_def = Some(def); match ii.node { ImplItemKind::Const(_, ref expr) => { @@ -270,7 +220,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { intravisit::walk_impl_item(self, ii); - self.parent_node = parent_node; + self.parent_def = parent_def; } fn visit_pat(&mut self, pat: &'ast Pat) { @@ -279,11 +229,184 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { _ => None }; + let parent_def = self.parent_def; if let Some(id) = maybe_binding { - self.insert_def(pat.id, NodeLocal(pat), DefPathData::Binding(id.name)); - } else { - self.insert(pat.id, NodePat(pat)); + let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + self.parent_def = Some(def); + } + + intravisit::walk_pat(self, pat); + self.parent_def = parent_def; + } + + fn visit_expr(&mut self, expr: &'ast Expr) { + let parent_def = self.parent_def; + + if let ExprClosure(..) = expr.node { + let def = self.create_def(expr.id, DefPathData::ClosureExpr); + self.parent_def = Some(def); + } + + intravisit::walk_expr(self, expr); + self.parent_def = parent_def; + } + + fn visit_stmt(&mut self, stmt: &'ast Stmt) { + intravisit::walk_stmt(self, stmt); + } + + fn visit_block(&mut self, block: &'ast Block) { + intravisit::walk_block(self, block); + } + + fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { + self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); + } + + fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { + self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); + } +} + +impl<'ast> NodeCollector<'ast> { + pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> { + let mut collector = NodeCollector { + krate: krate, + map: vec![], + parent_node: CRATE_NODE_ID, + }; + collector.insert_entry(CRATE_NODE_ID, RootCrate); + + collector + } + + pub fn extend(krate: &'ast Crate, + parent: &'ast InlinedItem, + parent_node: NodeId, + parent_def_path: DefPath, + parent_def_id: DefId, + map: Vec>) + -> NodeCollector<'ast> { + let mut collector = NodeCollector { + krate: krate, + map: map, + parent_node: parent_node, + }; + + assert_eq!(parent_def_path.krate, parent_def_id.krate); + collector.insert_entry(parent_node, RootInlinedParent(parent)); + + collector + } + + fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) { + debug!("ast_map: {:?} => {:?}", id, entry); + let len = self.map.len(); + if id as usize >= len { + self.map.extend(repeat(NotPresent).take(id as usize - len + 1)); } + self.map[id as usize] = entry; + } + + fn insert(&mut self, id: NodeId, node: Node<'ast>) { + let entry = MapEntry::from_node(self.parent_node, node); + self.insert_entry(id, entry); + } +} + +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) { + debug!("visit_nested_item: {:?}", item); + self.visit_item(self.krate.item(item.id)) + } + + fn visit_item(&mut self, i: &'ast Item) { + debug!("visit_item: {:?}", i); + + self.insert(i.id, NodeItem(i)); + + let parent_node = self.parent_node; + self.parent_node = i.id; + + match i.node { + ItemEnum(ref enum_definition, _) => { + for v in &enum_definition.variants { + self.insert(v.node.data.id(), NodeVariant(v)); + } + } + ItemStruct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + self.insert(struct_def.id(), NodeStructCtor(struct_def)); + } + } + ItemTrait(_, _, ref bounds, _) => { + for b in bounds.iter() { + if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { + self.insert(t.trait_ref.ref_id, NodeItem(i)); + } + } + } + ItemUse(ref view_path) => { + match view_path.node { + ViewPathList(_, ref paths) => { + for path in paths { + self.insert(path.node.id(), NodeItem(i)); + } + } + _ => () + } + } + _ => {} + } + intravisit::walk_item(self, i); + self.parent_node = parent_node; + } + + fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { + self.insert(foreign_item.id, NodeForeignItem(foreign_item)); + + let parent_node = self.parent_node; + self.parent_node = foreign_item.id; + intravisit::walk_foreign_item(self, foreign_item); + self.parent_node = parent_node; + } + + fn visit_generics(&mut self, generics: &'ast Generics) { + for ty_param in generics.ty_params.iter() { + self.insert(ty_param.id, NodeTyParam(ty_param)); + } + + intravisit::walk_generics(self, generics); + } + + fn visit_trait_item(&mut self, ti: &'ast TraitItem) { + self.insert(ti.id, NodeTraitItem(ti)); + + let parent_node = self.parent_node; + self.parent_node = ti.id; + + intravisit::walk_trait_item(self, ti); + + self.parent_node = parent_node; + } + + fn visit_impl_item(&mut self, ii: &'ast ImplItem) { + self.insert(ii.id, NodeImplItem(ii)); + + let parent_node = self.parent_node; + self.parent_node = ii.id; + + intravisit::walk_impl_item(self, ii); + + self.parent_node = parent_node; + } + + fn visit_pat(&mut self, pat: &'ast Pat) { + self.insert(pat.id, NodeLocal(pat)); let parent_node = self.parent_node; self.parent_node = pat.id; @@ -294,11 +417,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_expr(&mut self, expr: &'ast Expr) { self.insert(expr.id, NodeExpr(expr)); - match expr.node { - ExprClosure(..) => { self.create_def(expr.id, DefPathData::ClosureExpr); } - _ => { } - } - let parent_node = self.parent_node; self.parent_node = expr.id; intravisit::walk_expr(self, expr); @@ -331,13 +449,4 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { self.insert(lifetime.id, NodeLifetime(lifetime)); } - - fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { - self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); - self.visit_lifetime(&def.lifetime); - } - - fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { - self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); - } } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 7b8ddee0e23cb..6331f7d3009ee 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -10,7 +10,7 @@ pub use self::Node::*; use self::MapEntry::*; -use self::collector::NodeCollector; +use self::collector::{NodeCollector, DefCollector}; pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData, InlinedRootPath}; @@ -784,7 +784,14 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> { let (map, definitions) = { let mut collector = NodeCollector::root(&forest.krate); intravisit::walk_crate(&mut collector, &forest.krate); - (collector.map, collector.definitions) + + let definitions = { + let mut def_collector = DefCollector::root(&forest.krate, &collector.map); + intravisit::walk_crate(&mut def_collector, &forest.krate); + def_collector.definitions + }; + + (collector.map, definitions) }; if log_enabled!(::log::DEBUG) { @@ -836,19 +843,26 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let ii = map.forest.inlined_items.alloc(ii); let ii_parent_id = fld.new_id(DUMMY_NODE_ID); - let mut collector = - NodeCollector::extend( - map.krate(), - ii, - ii_parent_id, - parent_def_path, - parent_def_id, - mem::replace(&mut *map.map.borrow_mut(), vec![]), - mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); + let mut collector = NodeCollector::extend(map.krate(), + ii, + ii_parent_id, + parent_def_path.clone(), + parent_def_id, + mem::replace(&mut *map.map.borrow_mut(), vec![])); ii.visit(&mut collector); + { + let mut def_collector = DefCollector::extend(map.krate(), + ii_parent_id, + parent_def_path, + parent_def_id, + &collector.map, + mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); + ii.visit(&mut def_collector); + *map.definitions.borrow_mut() = def_collector.definitions; + } + *map.map.borrow_mut() = collector.map; - *map.definitions.borrow_mut() = collector.definitions; ii } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 9c444fca9a10e..c211fa2925e69 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -120,6 +120,27 @@ pub fn compile_input(sess: &Session, Ok(())); let expanded_crate = assign_node_ids(sess, expanded_crate); + let dep_graph = DepGraph::new(sess.opts.build_dep_graph); + + // TODO + // time(sess.time_passes(), + // "external crate/lib resolution", + // || LocalCrateReader::new(sess, &cstore, &defs, &id).read_crates()); + + // TODO + panic!(); + + // TODO CrateMap result + // let resolve::CrateMap { + // def_map, + // freevars, + // export_map, + // trait_map, + // glob_map, + // } = time(sess.time_passes(), + // "name resolution", + // || resolve::resolve_crate(sess, &hir_map, control.make_glob_map)); + // Lower ast -> hir. let lcx = LoweringContext::new(sess, Some(&expanded_crate)); let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); @@ -175,7 +196,6 @@ pub fn compile_input(sess: &Session, hir_map, &arenas, &id, - control.make_glob_map, |tcx, mir_map, analysis, result| { { // Eventually, we will want to track plugins. @@ -743,7 +763,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, hir_map: hir_map::Map<'tcx>, arenas: &'tcx ty::CtxtArenas<'tcx>, name: &str, - make_glob_map: resolve::MakeGlobMap, f: F) -> Result where F: FnOnce(&TyCtxt<'tcx>, Option>, ty::CrateAnalysis, CompileResult) -> R @@ -762,20 +781,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, let time_passes = sess.time_passes(); - time(time_passes, - "external crate/lib resolution", - || LocalCrateReader::new(sess, cstore, &hir_map, name).read_crates()); - - let resolve::CrateMap { - def_map, - freevars, - export_map, - trait_map, - glob_map, - } = time(time_passes, - "name resolution", - || resolve::resolve_crate(sess, &hir_map, make_glob_map)); - let lang_items = time(time_passes, "language item collection", || { sess.track_errors(|| { middle::lang_items::collect_language_items(&sess, &hir_map) From d6bcc04c521bcdf82b7727ec35e3f6ce0cbb5b0f Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 12:14:03 +1200 Subject: [PATCH 3/9] Move DefCollector to its own module. --- src/librustc/hir/map/collector.rs | 248 +------------------------ src/librustc/hir/map/def_collector.rs | 258 ++++++++++++++++++++++++++ src/librustc/hir/map/mod.rs | 7 +- src/librustc_driver/driver.rs | 2 +- 4 files changed, 267 insertions(+), 248 deletions(-) create mode 100644 src/librustc/hir/map/def_collector.rs diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 7f6a587fade24..d7fccf03aec75 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -1,4 +1,4 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015-2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -13,10 +13,10 @@ use super::MapEntry::*; use hir::*; use hir::intravisit::Visitor; -use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; +use hir::def_id::DefId; use middle::cstore::InlinedItem; use std::iter::repeat; -use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; +use syntax::ast::{NodeId, CRATE_NODE_ID}; use syntax::codemap::Span; /// A Visitor that walks over the HIR and collects Node's into a HIR map. @@ -26,248 +26,6 @@ pub struct NodeCollector<'ast> { pub parent_node: NodeId, } -pub struct DefCollector<'ast> { - pub krate: &'ast Crate, - pub map: &'ast [MapEntry<'ast>], - pub definitions: Definitions, - pub parent_def: Option, -} - -impl<'ast> DefCollector<'ast> { - pub fn root(krate: &'ast Crate, map: &'ast [MapEntry<'ast>]) -> DefCollector<'ast> { - let mut collector = DefCollector { - krate: krate, - map: map, - definitions: Definitions::new(), - parent_def: None, - }; - let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); - assert_eq!(result, CRATE_DEF_INDEX); - - collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc); - - collector - } - - pub fn extend(krate: &'ast Crate, - parent_node: NodeId, - parent_def_path: DefPath, - parent_def_id: DefId, - map: &'ast [MapEntry<'ast>], - definitions: Definitions) - -> DefCollector<'ast> { - let mut collector = DefCollector { - krate: krate, - map: map, - parent_def: None, - definitions: definitions, - }; - - assert_eq!(parent_def_path.krate, parent_def_id.krate); - let root_path = Box::new(InlinedRootPath { - data: parent_def_path.data, - def_id: parent_def_id, - }); - - let def = collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); - collector.parent_def = Some(def); - - collector - } - - fn parent_def(&self) -> Option { - self.parent_def - } - - fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex { - let parent_def = self.parent_def(); - debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); - self.definitions.create_def_with_parent(parent_def, node_id, data) - } - - fn create_def_with_parent(&mut self, - parent: Option, - node_id: NodeId, - data: DefPathData) - -> DefIndex { - self.definitions.create_def_with_parent(parent, node_id, data) - } -} - -impl<'ast> Visitor<'ast> for DefCollector<'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) { - debug!("visit_nested_item: {:?}", item); - self.visit_item(self.krate.item(item.id)) - } - - fn visit_item(&mut self, i: &'ast Item) { - debug!("visit_item: {:?}", i); - - // Pick the def data. This need not be unique, but the more - // information we encapsulate into - let def_data = match i.node { - ItemDefaultImpl(..) | ItemImpl(..) => - DefPathData::Impl, - ItemEnum(..) | ItemStruct(..) | ItemTrait(..) | - ItemExternCrate(..) | ItemForeignMod(..) | ItemTy(..) => - DefPathData::TypeNs(i.name), - ItemMod(..) => - DefPathData::Module(i.name), - ItemStatic(..) | ItemConst(..) | ItemFn(..) => - DefPathData::ValueNs(i.name), - ItemUse(..) => - DefPathData::Misc, - }; - - let def = self.create_def(i.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match i.node { - ItemEnum(ref enum_definition, _) => { - for v in &enum_definition.variants { - let variant_def_index = - self.create_def(v.node.data.id(), - DefPathData::EnumVariant(v.node.name)); - - for field in v.node.data.fields() { - self.create_def_with_parent( - Some(variant_def_index), - field.id, - DefPathData::Field(field.name)); - } - } - } - ItemStruct(ref struct_def, _) => { - // If this is a tuple-like struct, register the constructor. - if !struct_def.is_struct() { - self.create_def(struct_def.id(), - DefPathData::StructCtor); - } - - for field in struct_def.fields() { - self.create_def(field.id, DefPathData::Field(field.name)); - } - } - _ => {} - } - intravisit::walk_item(self, i); - self.parent_def = parent_def; - } - - fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { - let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - intravisit::walk_foreign_item(self, foreign_item); - self.parent_def = parent_def; - } - - fn visit_generics(&mut self, generics: &'ast Generics) { - for ty_param in generics.ty_params.iter() { - self.create_def(ty_param.id, - DefPathData::TypeParam(ty_param.name)); - } - - intravisit::walk_generics(self, generics); - } - - fn visit_trait_item(&mut self, ti: &'ast TraitItem) { - let def_data = match ti.node { - MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), - TypeTraitItem(..) => DefPathData::TypeNs(ti.name), - }; - - let def = self.create_def(ti.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match ti.node { - ConstTraitItem(_, Some(ref expr)) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - - intravisit::walk_trait_item(self, ti); - - self.parent_def = parent_def; - } - - fn visit_impl_item(&mut self, ii: &'ast ImplItem) { - let def_data = match ii.node { - ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), - ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), - }; - - let def = self.create_def(ii.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match ii.node { - ImplItemKind::Const(_, ref expr) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - - intravisit::walk_impl_item(self, ii); - - self.parent_def = parent_def; - } - - fn visit_pat(&mut self, pat: &'ast Pat) { - let maybe_binding = match pat.node { - PatKind::Ident(_, id, _) => Some(id.node), - _ => None - }; - - let parent_def = self.parent_def; - if let Some(id) = maybe_binding { - let def = self.create_def(pat.id, DefPathData::Binding(id.name)); - self.parent_def = Some(def); - } - - intravisit::walk_pat(self, pat); - self.parent_def = parent_def; - } - - fn visit_expr(&mut self, expr: &'ast Expr) { - let parent_def = self.parent_def; - - if let ExprClosure(..) = expr.node { - let def = self.create_def(expr.id, DefPathData::ClosureExpr); - self.parent_def = Some(def); - } - - intravisit::walk_expr(self, expr); - self.parent_def = parent_def; - } - - fn visit_stmt(&mut self, stmt: &'ast Stmt) { - intravisit::walk_stmt(self, stmt); - } - - fn visit_block(&mut self, block: &'ast Block) { - intravisit::walk_block(self, block); - } - - fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { - self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); - } - - fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { - self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); - } -} - impl<'ast> NodeCollector<'ast> { pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> { let mut collector = NodeCollector { diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs new file mode 100644 index 0000000000000..0e64a2d676e7d --- /dev/null +++ b/src/librustc/hir/map/def_collector.rs @@ -0,0 +1,258 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::*; + +use hir::*; +use hir::intravisit::Visitor; +use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; +use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; + +/// Creates def ids for nodes in the HIR. +pub struct DefCollector<'ast> { + pub krate: &'ast Crate, + pub map: &'ast [MapEntry<'ast>], + pub definitions: Definitions, + pub parent_def: Option, +} + +impl<'ast> DefCollector<'ast> { + pub fn root(krate: &'ast Crate, map: &'ast [MapEntry<'ast>]) -> DefCollector<'ast> { + let mut collector = DefCollector { + krate: krate, + map: map, + definitions: Definitions::new(), + parent_def: None, + }; + let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); + assert_eq!(result, CRATE_DEF_INDEX); + + collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc); + + collector + } + + pub fn extend(krate: &'ast Crate, + parent_node: NodeId, + parent_def_path: DefPath, + parent_def_id: DefId, + map: &'ast [MapEntry<'ast>], + definitions: Definitions) + -> DefCollector<'ast> { + let mut collector = DefCollector { + krate: krate, + map: map, + parent_def: None, + definitions: definitions, + }; + + assert_eq!(parent_def_path.krate, parent_def_id.krate); + let root_path = Box::new(InlinedRootPath { + data: parent_def_path.data, + def_id: parent_def_id, + }); + + let def = collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); + collector.parent_def = Some(def); + + collector + } + + fn parent_def(&self) -> Option { + self.parent_def + } + + fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex { + let parent_def = self.parent_def(); + debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); + self.definitions.create_def_with_parent(parent_def, node_id, data) + } + + fn create_def_with_parent(&mut self, + parent: Option, + node_id: NodeId, + data: DefPathData) + -> DefIndex { + self.definitions.create_def_with_parent(parent, node_id, data) + } +} + +impl<'ast> Visitor<'ast> for DefCollector<'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) { + debug!("visit_nested_item: {:?}", item); + self.visit_item(self.krate.item(item.id)) + } + + fn visit_item(&mut self, i: &'ast Item) { + debug!("visit_item: {:?}", i); + + // Pick the def data. This need not be unique, but the more + // information we encapsulate into + let def_data = match i.node { + ItemDefaultImpl(..) | ItemImpl(..) => + DefPathData::Impl, + ItemEnum(..) | ItemStruct(..) | ItemTrait(..) | + ItemExternCrate(..) | ItemMod(..) | ItemForeignMod(..) | + ItemTy(..) => + DefPathData::TypeNs(i.name), + ItemStatic(..) | ItemConst(..) | ItemFn(..) => + DefPathData::ValueNs(i.name), + ItemUse(..) => + DefPathData::Misc, + }; + + let def = self.create_def(i.id, def_data); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + + match i.node { + ItemEnum(ref enum_definition, _) => { + for v in &enum_definition.variants { + let variant_def_index = + self.create_def(v.node.data.id(), + DefPathData::EnumVariant(v.node.name)); + + for field in v.node.data.fields() { + self.create_def_with_parent( + Some(variant_def_index), + field.id, + DefPathData::Field(field.name)); + } + } + } + ItemStruct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + self.create_def(struct_def.id(), + DefPathData::StructCtor); + } + + for field in struct_def.fields() { + self.create_def(field.id, DefPathData::Field(field.name)); + } + } + _ => {} + } + intravisit::walk_item(self, i); + self.parent_def = parent_def; + } + + fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { + let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + intravisit::walk_foreign_item(self, foreign_item); + self.parent_def = parent_def; + } + + fn visit_generics(&mut self, generics: &'ast Generics) { + for ty_param in generics.ty_params.iter() { + self.create_def(ty_param.id, + DefPathData::TypeParam(ty_param.name)); + } + + intravisit::walk_generics(self, generics); + } + + fn visit_trait_item(&mut self, ti: &'ast TraitItem) { + let def_data = match ti.node { + MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), + TypeTraitItem(..) => DefPathData::TypeNs(ti.name), + }; + + let def = self.create_def(ti.id, def_data); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + + match ti.node { + ConstTraitItem(_, Some(ref expr)) => { + self.create_def(expr.id, DefPathData::Initializer); + } + _ => { } + } + + intravisit::walk_trait_item(self, ti); + + self.parent_def = parent_def; + } + + fn visit_impl_item(&mut self, ii: &'ast ImplItem) { + let def_data = match ii.node { + ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), + ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), + }; + + let def = self.create_def(ii.id, def_data); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + + match ii.node { + ImplItemKind::Const(_, ref expr) => { + self.create_def(expr.id, DefPathData::Initializer); + } + _ => { } + } + + intravisit::walk_impl_item(self, ii); + + self.parent_def = parent_def; + } + + fn visit_pat(&mut self, pat: &'ast Pat) { + let maybe_binding = match pat.node { + PatKind::Ident(_, id, _) => Some(id.node), + _ => None + }; + + let parent_def = self.parent_def; + if let Some(id) = maybe_binding { + let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + self.parent_def = Some(def); + } + + intravisit::walk_pat(self, pat); + self.parent_def = parent_def; + } + + fn visit_expr(&mut self, expr: &'ast Expr) { + let parent_def = self.parent_def; + + if let ExprClosure(..) = expr.node { + let def = self.create_def(expr.id, DefPathData::ClosureExpr); + self.parent_def = Some(def); + } + + intravisit::walk_expr(self, expr); + self.parent_def = parent_def; + } + + fn visit_stmt(&mut self, stmt: &'ast Stmt) { + intravisit::walk_stmt(self, stmt); + } + + fn visit_block(&mut self, block: &'ast Block) { + intravisit::walk_block(self, block); + } + + fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { + self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); + } + + fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { + self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); + } +} diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 6331f7d3009ee..d0ec83b7eb3a1 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -10,7 +10,8 @@ pub use self::Node::*; use self::MapEntry::*; -use self::collector::{NodeCollector, DefCollector}; +use self::collector::NodeCollector; +use self::def_collector::DefCollector; pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData, InlinedRootPath}; @@ -36,6 +37,7 @@ use std::mem; pub mod blocks; mod collector; +mod def_collector; pub mod definitions; #[derive(Copy, Clone, Debug)] @@ -852,12 +854,13 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, ii.visit(&mut collector); { + let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); let mut def_collector = DefCollector::extend(map.krate(), ii_parent_id, parent_def_path, parent_def_id, &collector.map, - mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); + defs); ii.visit(&mut def_collector); *map.definitions.borrow_mut() = def_collector.definitions; } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index c211fa2925e69..488e7ae56ef87 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -121,7 +121,7 @@ pub fn compile_input(sess: &Session, let expanded_crate = assign_node_ids(sess, expanded_crate); let dep_graph = DepGraph::new(sess.opts.build_dep_graph); - + // TODO // time(sess.time_passes(), // "external crate/lib resolution", From 6af7acab1c6976933c90b07a58450567227b4719 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 12:39:18 +1200 Subject: [PATCH 4/9] Separate def collection and hir map making even further --- src/librustc/hir/map/def_collector.rs | 6 +--- src/librustc/hir/map/mod.rs | 47 ++++++++++++--------------- src/librustc_driver/driver.rs | 20 ++++++------ src/librustc_driver/pretty.rs | 3 +- 4 files changed, 33 insertions(+), 43 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 0e64a2d676e7d..974791f62bbc4 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -18,16 +18,14 @@ use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; /// Creates def ids for nodes in the HIR. pub struct DefCollector<'ast> { pub krate: &'ast Crate, - pub map: &'ast [MapEntry<'ast>], pub definitions: Definitions, pub parent_def: Option, } impl<'ast> DefCollector<'ast> { - pub fn root(krate: &'ast Crate, map: &'ast [MapEntry<'ast>]) -> DefCollector<'ast> { + pub fn root(krate: &'ast Crate) -> DefCollector<'ast> { let mut collector = DefCollector { krate: krate, - map: map, definitions: Definitions::new(), parent_def: None, }; @@ -43,12 +41,10 @@ impl<'ast> DefCollector<'ast> { parent_node: NodeId, parent_def_path: DefPath, parent_def_id: DefId, - map: &'ast [MapEntry<'ast>], definitions: Definitions) -> DefCollector<'ast> { let mut collector = DefCollector { krate: krate, - map: map, parent_def: None, definitions: definitions, }; diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d0ec83b7eb3a1..70071c224f870 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -782,19 +782,16 @@ impl Folder for IdAndSpanUpdater { } } -pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> { - let (map, definitions) = { - let mut collector = NodeCollector::root(&forest.krate); - intravisit::walk_crate(&mut collector, &forest.krate); - - let definitions = { - let mut def_collector = DefCollector::root(&forest.krate, &collector.map); - intravisit::walk_crate(&mut def_collector, &forest.krate); - def_collector.definitions - }; +pub fn collect_definitions<'ast>(forest: &'ast mut Forest) -> Definitions { + let mut def_collector = DefCollector::root(&forest.krate); + intravisit::walk_crate(&mut def_collector, &forest.krate); + def_collector.definitions +} - (collector.map, definitions) - }; +pub fn map_crate<'ast>(forest: &'ast mut Forest, definitions: Definitions) -> Map<'ast> { + let mut collector = NodeCollector::root(&forest.krate); + intravisit::walk_crate(&mut collector, &forest.krate); + let map = collector.map; if log_enabled!(::log::DEBUG) { // This only makes sense for ordered stores; note the @@ -843,28 +840,24 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, }; let ii = map.forest.inlined_items.alloc(ii); - let ii_parent_id = fld.new_id(DUMMY_NODE_ID); + + let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); + let mut def_collector = DefCollector::extend(map.krate(), + ii_parent_id, + parent_def_path.clone(), + parent_def_id, + defs); + ii.visit(&mut def_collector); + *map.definitions.borrow_mut() = def_collector.definitions; + let mut collector = NodeCollector::extend(map.krate(), ii, ii_parent_id, - parent_def_path.clone(), + parent_def_path, parent_def_id, mem::replace(&mut *map.map.borrow_mut(), vec![])); ii.visit(&mut collector); - - { - let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); - let mut def_collector = DefCollector::extend(map.krate(), - ii_parent_id, - parent_def_path, - parent_def_id, - &collector.map, - defs); - ii.visit(&mut def_collector); - *map.definitions.borrow_mut() = def_collector.definitions; - } - *map.map.borrow_mut() = collector.map; ii diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 488e7ae56ef87..d63cf8756325a 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -156,7 +156,16 @@ pub fn compile_input(sess: &Session, } let arenas = ty::CtxtArenas::new(); - let hir_map = make_map(sess, &mut hir_forest); + // Collect defintions for def ids. + let defs = time(sess.time_passes(), + "collecting defs", + move || hir_map::collect_defs(hir_forest)); + + // Construct the HIR map + let hir_map = time(sess.time_passes(), + "indexing hir", + move || hir_map::map_crate(hir_forest, defs)); + write_out_deps(sess, &outputs, &id); @@ -746,15 +755,6 @@ pub fn assign_node_ids(sess: &Session, krate: ast::Crate) -> ast::Crate { krate } -pub fn make_map<'ast>(sess: &Session, - forest: &'ast mut hir_map::Forest) - -> hir_map::Map<'ast> { - // Construct the HIR map - time(sess.time_passes(), - "indexing hir", - move || hir_map::map_crate(forest)) -} - /// Run the resolution, typechecking, region checking and other /// miscellaneous analysis passes on the crate. Return various /// structures carrying the results of the analysis. diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index cde5ba19859e0..228cb8d75afef 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -738,7 +738,8 @@ pub fn pretty_print_input(sess: Session, let _ignore = dep_graph.in_ignore(); let ast_map = if compute_ast_map { hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); - let map = driver::make_map(&sess, &mut hir_forest); + let defs = hir_map::collect_defs(hir_forest); + let map = hir_map::map_crate(hir_forest, defs); Some(map) } else { None From 84c3f898f93e294f2e50ceef271bd781b1ff6b9a Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 14:51:21 +1200 Subject: [PATCH 5/9] def_collector and crate reader operate on AST instead of HIR And move extern crate reading earlier in the driver --- src/librustc/hir/map/def_collector.rs | 92 +++++++++++++-------------- src/librustc/hir/map/mod.rs | 28 ++++---- src/librustc_driver/driver.rs | 54 ++++++++-------- src/librustc_driver/pretty.rs | 10 +-- src/librustc_metadata/creader.rs | 80 ++++++++--------------- 5 files changed, 113 insertions(+), 151 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 974791f62bbc4..a259c5a0f3147 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -10,10 +10,10 @@ use super::*; -use hir::*; -use hir::intravisit::Visitor; use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; -use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; + +use syntax::ast::*; +use syntax::visit; /// Creates def ids for nodes in the HIR. pub struct DefCollector<'ast> { @@ -80,31 +80,23 @@ impl<'ast> DefCollector<'ast> { } } -impl<'ast> Visitor<'ast> for DefCollector<'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) { - debug!("visit_nested_item: {:?}", item); - self.visit_item(self.krate.item(item.id)) - } - +impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { fn visit_item(&mut self, i: &'ast Item) { debug!("visit_item: {:?}", i); // Pick the def data. This need not be unique, but the more // information we encapsulate into let def_data = match i.node { - ItemDefaultImpl(..) | ItemImpl(..) => + ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => DefPathData::Impl, - ItemEnum(..) | ItemStruct(..) | ItemTrait(..) | - ItemExternCrate(..) | ItemMod(..) | ItemForeignMod(..) | - ItemTy(..) => - DefPathData::TypeNs(i.name), - ItemStatic(..) | ItemConst(..) | ItemFn(..) => - DefPathData::ValueNs(i.name), - ItemUse(..) => - DefPathData::Misc, + ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Trait(..) | + ItemKind::ExternCrate(..) | ItemKind::Mod(..) | ItemKind::ForeignMod(..) | + ItemKind::Ty(..) => + DefPathData::TypeNs(i.ident.name), + ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => + DefPathData::ValueNs(i.ident.name), + ItemKind::Mac(..) => DefPathData::MacroDef(i.ident.name), + ItemKind::Use(..) => DefPathData::Misc, }; let def = self.create_def(i.id, def_data); @@ -113,21 +105,22 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { self.parent_def = Some(def); match i.node { - ItemEnum(ref enum_definition, _) => { + ItemKind::Enum(ref enum_definition, _) => { for v in &enum_definition.variants { let variant_def_index = self.create_def(v.node.data.id(), - DefPathData::EnumVariant(v.node.name)); + DefPathData::EnumVariant(v.node.name.name)); for field in v.node.data.fields() { - self.create_def_with_parent( - Some(variant_def_index), - field.id, - DefPathData::Field(field.name)); + if let Some(ident) = field.ident { + self.create_def_with_parent(Some(variant_def_index), + field.id, + DefPathData::Field(ident.name)); + } } } } - ItemStruct(ref struct_def, _) => { + ItemKind::Struct(ref struct_def, _) => { // If this is a tuple-like struct, register the constructor. if !struct_def.is_struct() { self.create_def(struct_def.id(), @@ -135,37 +128,40 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { } for field in struct_def.fields() { - self.create_def(field.id, DefPathData::Field(field.name)); + if let Some(ident) = field.ident { + self.create_def(field.id, DefPathData::Field(ident.name)); + } } } _ => {} } - intravisit::walk_item(self, i); + visit::walk_item(self, i); self.parent_def = parent_def; } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { - let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); + let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.ident.name)); let parent_def = self.parent_def; self.parent_def = Some(def); - intravisit::walk_foreign_item(self, foreign_item); + visit::walk_foreign_item(self, foreign_item); self.parent_def = parent_def; } fn visit_generics(&mut self, generics: &'ast Generics) { for ty_param in generics.ty_params.iter() { self.create_def(ty_param.id, - DefPathData::TypeParam(ty_param.name)); + DefPathData::TypeParam(ty_param.ident.name)); } - intravisit::walk_generics(self, generics); + visit::walk_generics(self, generics); } fn visit_trait_item(&mut self, ti: &'ast TraitItem) { let def_data = match ti.node { - MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), - TypeTraitItem(..) => DefPathData::TypeNs(ti.name), + TraitItemKind::Method(..) | TraitItemKind::Const(..) => + DefPathData::ValueNs(ti.ident.name), + TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name), }; let def = self.create_def(ti.id, def_data); @@ -174,21 +170,23 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { self.parent_def = Some(def); match ti.node { - ConstTraitItem(_, Some(ref expr)) => { + TraitItemKind::Const(_, Some(ref expr)) => { self.create_def(expr.id, DefPathData::Initializer); } _ => { } } - intravisit::walk_trait_item(self, ti); + visit::walk_trait_item(self, ti); self.parent_def = parent_def; } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { let def_data = match ii.node { - ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), - ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), + ImplItemKind::Method(..) | ImplItemKind::Const(..) => + DefPathData::ValueNs(ii.ident.name), + ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name), + ImplItemKind::Macro(..) => DefPathData::MacroDef(ii.ident.name), }; let def = self.create_def(ii.id, def_data); @@ -203,7 +201,7 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { _ => { } } - intravisit::walk_impl_item(self, ii); + visit::walk_impl_item(self, ii); self.parent_def = parent_def; } @@ -220,28 +218,28 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { self.parent_def = Some(def); } - intravisit::walk_pat(self, pat); + visit::walk_pat(self, pat); self.parent_def = parent_def; } fn visit_expr(&mut self, expr: &'ast Expr) { let parent_def = self.parent_def; - if let ExprClosure(..) = expr.node { + if let ExprKind::Closure(..) = expr.node { let def = self.create_def(expr.id, DefPathData::ClosureExpr); self.parent_def = Some(def); } - intravisit::walk_expr(self, expr); + visit::walk_expr(self, expr); self.parent_def = parent_def; } fn visit_stmt(&mut self, stmt: &'ast Stmt) { - intravisit::walk_stmt(self, stmt); + visit::walk_stmt(self, stmt); } fn visit_block(&mut self, block: &'ast Block) { - intravisit::walk_block(self, block); + visit::walk_block(self, block); } fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { @@ -249,6 +247,6 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { } fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { - self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); + self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name)); } } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 70071c224f870..b1954255278c0 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -22,9 +22,10 @@ use middle::cstore::InlinedItem as II; use hir::def_id::{CRATE_DEF_INDEX, DefId}; use syntax::abi::Abi; -use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID}; +use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, }; use syntax::attr::ThinAttributesExt; use syntax::codemap::{Span, Spanned}; +use syntax::visit; use hir::*; use hir::fold::Folder; @@ -782,10 +783,10 @@ impl Folder for IdAndSpanUpdater { } } -pub fn collect_definitions<'ast>(forest: &'ast mut Forest) -> Definitions { - let mut def_collector = DefCollector::root(&forest.krate); - intravisit::walk_crate(&mut def_collector, &forest.krate); - def_collector.definitions +pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions { + let mut def_collector = DefCollector::root(krate); + visit::walk_crate(&mut def_collector, krate); + def_collector.definitions } pub fn map_crate<'ast>(forest: &'ast mut Forest, definitions: Definitions) -> Map<'ast> { @@ -842,14 +843,15 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let ii = map.forest.inlined_items.alloc(ii); let ii_parent_id = fld.new_id(DUMMY_NODE_ID); - let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); - let mut def_collector = DefCollector::extend(map.krate(), - ii_parent_id, - parent_def_path.clone(), - parent_def_id, - defs); - ii.visit(&mut def_collector); - *map.definitions.borrow_mut() = def_collector.definitions; + // TODO need to save defs in metadata :-( + // let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); + // let mut def_collector = DefCollector::extend(map.krate(), + // ii_parent_id, + // parent_def_path.clone(), + // parent_def_id, + // defs); + // ii.visit(&mut def_collector); + // *map.definitions.borrow_mut() = def_collector.definitions; let mut collector = NodeCollector::extend(map.krate(), ii, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index d63cf8756325a..6724c0ed8ebfd 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -122,32 +122,22 @@ pub fn compile_input(sess: &Session, let expanded_crate = assign_node_ids(sess, expanded_crate); let dep_graph = DepGraph::new(sess.opts.build_dep_graph); - // TODO - // time(sess.time_passes(), - // "external crate/lib resolution", - // || LocalCrateReader::new(sess, &cstore, &defs, &id).read_crates()); - - // TODO - panic!(); - - // TODO CrateMap result - // let resolve::CrateMap { - // def_map, - // freevars, - // export_map, - // trait_map, - // glob_map, - // } = time(sess.time_passes(), - // "name resolution", - // || resolve::resolve_crate(sess, &hir_map, control.make_glob_map)); + // Collect defintions for def ids. + let defs = time(sess.time_passes(), + "collecting defs", + || hir_map::collect_definitions(&expanded_crate)); + + time(sess.time_passes(), + "external crate/lib resolution", + || LocalCrateReader::new(sess, &cstore, &defs, &expanded_crate, &id) + .read_crates(&dep_graph)); // Lower ast -> hir. let lcx = LoweringContext::new(sess, Some(&expanded_crate)); - let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); - let mut hir_forest = time(sess.time_passes(), - "lowering ast -> hir", - || hir_map::Forest::new(lower_crate(&lcx, &expanded_crate), - dep_graph)); + let hir_forest = &mut time(sess.time_passes(), + "lowering ast -> hir", + || hir_map::Forest::new(lower_crate(&lcx, &expanded_crate), + dep_graph)); // Discard MTWT tables that aren't required past lowering to HIR. if !sess.opts.debugging_opts.keep_mtwt_tables && @@ -156,10 +146,6 @@ pub fn compile_input(sess: &Session, } let arenas = ty::CtxtArenas::new(); - // Collect defintions for def ids. - let defs = time(sess.time_passes(), - "collecting defs", - move || hir_map::collect_defs(hir_forest)); // Construct the HIR map let hir_map = time(sess.time_passes(), @@ -201,10 +187,10 @@ pub fn compile_input(sess: &Session, }; phase_3_run_analysis_passes(sess, - &cstore, hir_map, &arenas, &id, + control.make_glob_map, |tcx, mir_map, analysis, result| { { // Eventually, we will want to track plugins. @@ -759,10 +745,10 @@ pub fn assign_node_ids(sess: &Session, krate: ast::Crate) -> ast::Crate { /// miscellaneous analysis passes on the crate. Return various /// structures carrying the results of the analysis. pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, - cstore: &CStore, hir_map: hir_map::Map<'tcx>, arenas: &'tcx ty::CtxtArenas<'tcx>, name: &str, + make_glob_map: resolve::MakeGlobMap, f: F) -> Result where F: FnOnce(&TyCtxt<'tcx>, Option>, ty::CrateAnalysis, CompileResult) -> R @@ -787,6 +773,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, }) })?; + let resolve::CrateMap { + def_map, + freevars, + export_map, + trait_map, + glob_map, + } = time(sess.time_passes(), + "name resolution", + || resolve::resolve_crate(sess, &hir_map, make_glob_map)); + let mut analysis = ty::CrateAnalysis { export_map: export_map, access_levels: AccessLevels::default(), diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 228cb8d75afef..2e3a477e04840 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -179,7 +179,6 @@ impl PpSourceMode { } fn call_with_pp_support_hir<'tcx, A, B, F>(&self, sess: &'tcx Session, - cstore: &CStore, ast_map: &hir_map::Map<'tcx>, arenas: &'tcx ty::CtxtArenas<'tcx>, id: &str, @@ -206,7 +205,6 @@ impl PpSourceMode { } PpmTyped => { abort_on_err(driver::phase_3_run_analysis_passes(sess, - cstore, ast_map.clone(), arenas, id, @@ -737,9 +735,9 @@ pub fn pretty_print_input(sess: Session, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); let ast_map = if compute_ast_map { + let defs = hir_map::collect_definitions(&krate); hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); - let defs = hir_map::collect_defs(hir_forest); - let map = hir_map::map_crate(hir_forest, defs); + let map = hir_map::map_crate(&mut hir_forest, defs); Some(map) } else { None @@ -778,7 +776,6 @@ pub fn pretty_print_input(sess: Session, (PpmHir(s), None) => { let out: &mut Write = &mut out; s.call_with_pp_support_hir(&sess, - cstore, &ast_map.unwrap(), &arenas, &id, @@ -800,7 +797,6 @@ pub fn pretty_print_input(sess: Session, (PpmHir(s), Some(uii)) => { let out: &mut Write = &mut out; s.call_with_pp_support_hir(&sess, - cstore, &ast_map.unwrap(), &arenas, &id, @@ -841,7 +837,6 @@ pub fn pretty_print_input(sess: Session, None }; abort_on_err(driver::phase_3_run_analysis_passes(&sess, - &cstore, ast_map, &arenas, &id, @@ -888,7 +883,6 @@ pub fn pretty_print_input(sess: Session, Some(code) => { let variants = gather_flowgraph_variants(&sess); abort_on_err(driver::phase_3_run_analysis_passes(&sess, - &cstore, ast_map, &arenas, &id, diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 8ec238f4b248f..4ba59a3d7ebe9 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -18,7 +18,7 @@ use decoder; use loader::{self, CratePaths}; use rustc::hir::svh::Svh; -use rustc::dep_graph::DepNode; +use rustc::dep_graph::{DepGraph, DepNode}; use rustc::session::{config, Session}; use rustc::session::search_paths::PathKind; use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate}; @@ -37,15 +37,15 @@ use syntax::parse; use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::parse::token::InternedString; -use rustc::hir::intravisit::Visitor; -use rustc::hir; +use syntax::visit; use log; -pub struct LocalCrateReader<'a, 'b:'a> { +pub struct LocalCrateReader<'a> { sess: &'a Session, cstore: &'a CStore, creader: CrateReader<'a>, - ast_map: &'a hir_map::Map<'b>, + krate: &'a ast::Crate, + defintions: &'a hir_map::Definitions, } pub struct CrateReader<'a> { @@ -56,8 +56,8 @@ pub struct CrateReader<'a> { local_crate_name: String, } -impl<'a, 'b, 'hir> Visitor<'hir> for LocalCrateReader<'a, 'b> { - fn visit_item(&mut self, a: &'hir hir::Item) { +impl<'a, 'ast> visit::Visitor<'ast> for LocalCrateReader<'a> { + fn visit_item(&mut self, a: &'ast ast::Item) { self.process_item(a); } } @@ -80,10 +80,6 @@ fn dump_crates(cstore: &CStore) { fn should_link(i: &ast::Item) -> bool { !attr::contains_name(&i.attrs, "no_link") } -// Dup for the hir -fn should_link_hir(i: &hir::Item) -> bool { - !attr::contains_name(&i.attrs, "no_link") -} struct CrateInfo { ident: String, @@ -181,31 +177,6 @@ impl<'a> CrateReader<'a> { } } - // Dup of the above, but for the hir - fn extract_crate_info_hir(&self, i: &hir::Item) -> Option { - match i.node { - hir::ItemExternCrate(ref path_opt) => { - debug!("resolving extern crate stmt. ident: {} path_opt: {:?}", - i.name, path_opt); - let name = match *path_opt { - Some(name) => { - validate_crate_name(Some(self.sess), &name.as_str(), - Some(i.span)); - name.to_string() - } - None => i.name.to_string(), - }; - Some(CrateInfo { - ident: i.name.to_string(), - name: name, - id: i.id, - should_link: should_link_hir(i), - }) - } - _ => None - } - } - fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind) -> Option { let mut ret = None; @@ -776,29 +747,30 @@ impl<'a> CrateReader<'a> { } } -impl<'a, 'b> LocalCrateReader<'a, 'b> { +impl<'a> LocalCrateReader<'a> { pub fn new(sess: &'a Session, cstore: &'a CStore, - map: &'a hir_map::Map<'b>, + defs: &'a hir_map::Definitions, + krate: &'a ast::Crate, local_crate_name: &str) - -> LocalCrateReader<'a, 'b> { + -> LocalCrateReader<'a> { LocalCrateReader { sess: sess, cstore: cstore, creader: CrateReader::new(sess, cstore, local_crate_name), - ast_map: map, + krate: krate, + defintions: defs, } } // Traverses an AST, reading all the information about use'd crates and // extern libraries necessary for later resolving, typechecking, linking, // etc. - pub fn read_crates(&mut self) { - let _task = self.ast_map.dep_graph.in_task(DepNode::CrateReader); - let krate = self.ast_map.krate(); + pub fn read_crates(&mut self, dep_graph: &DepGraph) { + let _task = dep_graph.in_task(DepNode::CrateReader); - self.process_crate(krate); - krate.visit_all_items(self); + self.process_crate(self.krate); + visit::walk_crate(self, self.krate); self.creader.inject_allocator_crate(); if log_enabled!(log::INFO) { @@ -811,7 +783,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { self.creader.register_statically_included_foreign_items(); } - fn process_crate(&self, c: &hir::Crate) { + fn process_crate(&self, c: &ast::Crate) { for a in c.attrs.iter().filter(|m| m.name() == "link_args") { if let Some(ref linkarg) = a.value_str() { self.cstore.add_used_link_args(&linkarg); @@ -819,14 +791,14 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { } } - fn process_item(&mut self, i: &hir::Item) { + fn process_item(&mut self, i: &ast::Item) { match i.node { - hir::ItemExternCrate(_) => { - if !should_link_hir(i) { + ast::ItemKind::ExternCrate(_) => { + if !should_link(i) { return; } - match self.creader.extract_crate_info_hir(i) { + match self.creader.extract_crate_info(i) { Some(info) => { let (cnum, _, _) = self.creader.resolve_crate(&None, &info.ident, @@ -835,9 +807,9 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { i.span, PathKind::Crate, true); - let def_id = self.ast_map.local_def_id(i.id); + let def_id = self.defintions.opt_local_def_id(i.id).unwrap(); - let len = self.ast_map.def_path(def_id).data.len(); + let len = self.defintions.def_path(def_id.index).data.len(); self.creader.update_extern_crate(cnum, ExternCrate { @@ -851,12 +823,12 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { None => () } } - hir::ItemForeignMod(ref fm) => self.process_foreign_mod(i, fm), + ast::ItemKind::ForeignMod(ref fm) => self.process_foreign_mod(i, fm), _ => { } } } - fn process_foreign_mod(&mut self, i: &hir::Item, fm: &hir::ForeignMod) { + fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) { if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic { return; } From 0c37d4bb1d1b8df21e1e4c8a634127cee871f7ab Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 17:24:30 +1200 Subject: [PATCH 6/9] refactoring --- src/librustc/hir/map/collector.rs | 115 +++++++++++----------- src/librustc/hir/map/def_collector.rs | 132 +++++++++++--------------- src/librustc/hir/map/mod.rs | 5 +- 3 files changed, 111 insertions(+), 141 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index d7fccf03aec75..c9d93319c03a8 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -70,6 +70,13 @@ impl<'ast> NodeCollector<'ast> { let entry = MapEntry::from_node(self.parent_node, node); self.insert_entry(id, entry); } + + fn with_parent(&mut self, parent_id: NodeId, f: F) { + let parent_node = self.parent_node; + self.parent_node = parent_id; + f(self); + self.parent_node = parent_node; + } } impl<'ast> Visitor<'ast> for NodeCollector<'ast> { @@ -86,51 +93,48 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.insert(i.id, NodeItem(i)); - let parent_node = self.parent_node; - self.parent_node = i.id; - - match i.node { - ItemEnum(ref enum_definition, _) => { - for v in &enum_definition.variants { - self.insert(v.node.data.id(), NodeVariant(v)); + self.with_parent(i.id, |this| { + match i.node { + ItemEnum(ref enum_definition, _) => { + for v in &enum_definition.variants { + this.insert(v.node.data.id(), NodeVariant(v)); + } } - } - ItemStruct(ref struct_def, _) => { - // If this is a tuple-like struct, register the constructor. - if !struct_def.is_struct() { - self.insert(struct_def.id(), NodeStructCtor(struct_def)); + ItemStruct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + this.insert(struct_def.id(), NodeStructCtor(struct_def)); + } } - } - ItemTrait(_, _, ref bounds, _) => { - for b in bounds.iter() { - if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { - self.insert(t.trait_ref.ref_id, NodeItem(i)); + ItemTrait(_, _, ref bounds, _) => { + for b in bounds.iter() { + if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { + this.insert(t.trait_ref.ref_id, NodeItem(i)); + } } } - } - ItemUse(ref view_path) => { - match view_path.node { - ViewPathList(_, ref paths) => { - for path in paths { - self.insert(path.node.id(), NodeItem(i)); + ItemUse(ref view_path) => { + match view_path.node { + ViewPathList(_, ref paths) => { + for path in paths { + this.insert(path.node.id(), NodeItem(i)); + } } + _ => () } - _ => () } + _ => {} } - _ => {} - } - intravisit::walk_item(self, i); - self.parent_node = parent_node; + intravisit::walk_item(this, i); + }); } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { self.insert(foreign_item.id, NodeForeignItem(foreign_item)); - let parent_node = self.parent_node; - self.parent_node = foreign_item.id; - intravisit::walk_foreign_item(self, foreign_item); - self.parent_node = parent_node; + self.with_parent(foreign_item.id, |this| { + intravisit::walk_foreign_item(this, foreign_item); + }); } fn visit_generics(&mut self, generics: &'ast Generics) { @@ -144,50 +148,42 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_trait_item(&mut self, ti: &'ast TraitItem) { self.insert(ti.id, NodeTraitItem(ti)); - let parent_node = self.parent_node; - self.parent_node = ti.id; - - intravisit::walk_trait_item(self, ti); - - self.parent_node = parent_node; + self.with_parent(ti.id, |this| { + intravisit::walk_trait_item(this, ti); + }); } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { self.insert(ii.id, NodeImplItem(ii)); - let parent_node = self.parent_node; - self.parent_node = ii.id; - - intravisit::walk_impl_item(self, ii); - - self.parent_node = parent_node; + self.with_parent(ii.id, |this| { + intravisit::walk_impl_item(this, ii); + }); } fn visit_pat(&mut self, pat: &'ast Pat) { self.insert(pat.id, NodeLocal(pat)); - let parent_node = self.parent_node; - self.parent_node = pat.id; - intravisit::walk_pat(self, pat); - self.parent_node = parent_node; + self.with_parent(pat.id, |this| { + intravisit::walk_pat(this, pat); + }); } fn visit_expr(&mut self, expr: &'ast Expr) { self.insert(expr.id, NodeExpr(expr)); - let parent_node = self.parent_node; - self.parent_node = expr.id; - intravisit::walk_expr(self, expr); - self.parent_node = parent_node; + self.with_parent(expr.id, |this| { + intravisit::walk_expr(this, expr); + }); } fn visit_stmt(&mut self, stmt: &'ast Stmt) { let id = stmt.node.id(); self.insert(id, NodeStmt(stmt)); - let parent_node = self.parent_node; - self.parent_node = id; - intravisit::walk_stmt(self, stmt); - self.parent_node = parent_node; + + self.with_parent(id, |this| { + intravisit::walk_stmt(this, stmt); + }); } fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, @@ -198,10 +194,9 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { 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; - intravisit::walk_block(self, block); - self.parent_node = parent_node; + self.with_parent(block.id, |this| { + intravisit::walk_block(this, block); + }); } fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index a259c5a0f3147..9d6027932f6de 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -16,16 +16,14 @@ use syntax::ast::*; use syntax::visit; /// Creates def ids for nodes in the HIR. -pub struct DefCollector<'ast> { - pub krate: &'ast Crate, +pub struct DefCollector { pub definitions: Definitions, pub parent_def: Option, } -impl<'ast> DefCollector<'ast> { - pub fn root(krate: &'ast Crate) -> DefCollector<'ast> { +impl DefCollector { + pub fn root() -> DefCollector { let mut collector = DefCollector { - krate: krate, definitions: Definitions::new(), parent_def: None, }; @@ -37,14 +35,12 @@ impl<'ast> DefCollector<'ast> { collector } - pub fn extend(krate: &'ast Crate, - parent_node: NodeId, + pub fn extend(parent_node: NodeId, parent_def_path: DefPath, parent_def_id: DefId, definitions: Definitions) - -> DefCollector<'ast> { + -> DefCollector { let mut collector = DefCollector { - krate: krate, parent_def: None, definitions: definitions, }; @@ -78,9 +74,16 @@ impl<'ast> DefCollector<'ast> { -> DefIndex { self.definitions.create_def_with_parent(parent, node_id, data) } + + fn with_parent(&mut self, parent_def: DefIndex, f: F) { + let parent = self.parent_def; + self.parent_def = Some(parent_def); + f(self); + self.parent_def = parent; + } } -impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { +impl<'ast> visit::Visitor<'ast> for DefCollector { fn visit_item(&mut self, i: &'ast Item) { debug!("visit_item: {:?}", i); @@ -98,60 +101,55 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { ItemKind::Mac(..) => DefPathData::MacroDef(i.ident.name), ItemKind::Use(..) => DefPathData::Misc, }; - let def = self.create_def(i.id, def_data); - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match i.node { - ItemKind::Enum(ref enum_definition, _) => { - for v in &enum_definition.variants { - let variant_def_index = - self.create_def(v.node.data.id(), - DefPathData::EnumVariant(v.node.name.name)); - - for field in v.node.data.fields() { - if let Some(ident) = field.ident { - self.create_def_with_parent(Some(variant_def_index), - field.id, - DefPathData::Field(ident.name)); + self.with_parent(def, |this| { + match i.node { + ItemKind::Enum(ref enum_definition, _) => { + for v in &enum_definition.variants { + let variant_def_index = + this.create_def(v.node.data.id(), + DefPathData::EnumVariant(v.node.name.name)); + + for field in v.node.data.fields() { + if let Some(ident) = field.ident { + this.create_def_with_parent(Some(variant_def_index), + field.id, + DefPathData::Field(ident.name)); + } } } } - } - ItemKind::Struct(ref struct_def, _) => { - // If this is a tuple-like struct, register the constructor. - if !struct_def.is_struct() { - self.create_def(struct_def.id(), - DefPathData::StructCtor); - } + ItemKind::Struct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + this.create_def(struct_def.id(), + DefPathData::StructCtor); + } - for field in struct_def.fields() { - if let Some(ident) = field.ident { - self.create_def(field.id, DefPathData::Field(ident.name)); + for field in struct_def.fields() { + if let Some(ident) = field.ident { + this.create_def(field.id, DefPathData::Field(ident.name)); + } } } + _ => {} } - _ => {} - } - visit::walk_item(self, i); - self.parent_def = parent_def; + visit::walk_item(this, i); + }); } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.ident.name)); - let parent_def = self.parent_def; - self.parent_def = Some(def); - visit::walk_foreign_item(self, foreign_item); - self.parent_def = parent_def; + self.with_parent(def, |this| { + visit::walk_foreign_item(this, foreign_item); + }); } fn visit_generics(&mut self, generics: &'ast Generics) { for ty_param in generics.ty_params.iter() { - self.create_def(ty_param.id, - DefPathData::TypeParam(ty_param.ident.name)); + self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.ident.name)); } visit::walk_generics(self, generics); @@ -165,20 +163,13 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { }; let def = self.create_def(ti.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match ti.node { - TraitItemKind::Const(_, Some(ref expr)) => { - self.create_def(expr.id, DefPathData::Initializer); + self.with_parent(def, |this| { + if let TraitItemKind::Const(_, Some(ref expr)) = ti.node { + this.create_def(expr.id, DefPathData::Initializer); } - _ => { } - } - - visit::walk_trait_item(self, ti); - self.parent_def = parent_def; + visit::walk_trait_item(this, ti); + }); } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { @@ -190,20 +181,13 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { }; let def = self.create_def(ii.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match ii.node { - ImplItemKind::Const(_, ref expr) => { - self.create_def(expr.id, DefPathData::Initializer); + self.with_parent(def, |this| { + if let ImplItemKind::Const(_, ref expr) = ii.node { + this.create_def(expr.id, DefPathData::Initializer); } - _ => { } - } - - visit::walk_impl_item(self, ii); - self.parent_def = parent_def; + visit::walk_impl_item(this, ii); + }); } fn visit_pat(&mut self, pat: &'ast Pat) { @@ -234,14 +218,6 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { self.parent_def = parent_def; } - fn visit_stmt(&mut self, stmt: &'ast Stmt) { - visit::walk_stmt(self, stmt); - } - - fn visit_block(&mut self, block: &'ast Block) { - visit::walk_block(self, block); - } - fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b1954255278c0..a505ad198896f 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -784,7 +784,7 @@ impl Folder for IdAndSpanUpdater { } pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions { - let mut def_collector = DefCollector::root(krate); + let mut def_collector = DefCollector::root(); visit::walk_crate(&mut def_collector, krate); def_collector.definitions } @@ -845,8 +845,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, // TODO need to save defs in metadata :-( // let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); - // let mut def_collector = DefCollector::extend(map.krate(), - // ii_parent_id, + // let mut def_collector = DefCollector::extend(ii_parent_id, // parent_def_path.clone(), // parent_def_id, // defs); From 744be0b5aac8c06c60dabac3a7802a8117c946b2 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 18:04:55 +1200 Subject: [PATCH 7/9] HIR visitor for DefCollector So that we can work with inlined HIR from metadata. --- src/librustc/hir/map/def_collector.rs | 174 +++++++++++++++++++++++++- src/librustc/hir/map/mod.rs | 15 ++- 2 files changed, 175 insertions(+), 14 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 9d6027932f6de..f8d0243548fd1 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -10,20 +10,28 @@ use super::*; +use hir; +use hir::intravisit; use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; +use middle::cstore::InlinedItem; + use syntax::ast::*; use syntax::visit; /// Creates def ids for nodes in the HIR. -pub struct DefCollector { +pub struct DefCollector<'ast> { + // If we are walking HIR (c.f., AST), we need to keep a reference to the + // crate. + hir_crate: Option<&'ast hir::Crate>, pub definitions: Definitions, - pub parent_def: Option, + parent_def: Option, } -impl DefCollector { - pub fn root() -> DefCollector { +impl<'ast> DefCollector<'ast> { + pub fn root() -> DefCollector<'ast> { let mut collector = DefCollector { + hir_crate: None, definitions: Definitions::new(), parent_def: None, }; @@ -39,8 +47,9 @@ impl DefCollector { parent_def_path: DefPath, parent_def_id: DefId, definitions: Definitions) - -> DefCollector { + -> DefCollector<'ast> { let mut collector = DefCollector { + hir_crate: None, parent_def: None, definitions: definitions, }; @@ -57,6 +66,11 @@ impl DefCollector { collector } + pub fn walk_item(&mut self, ii: &'ast InlinedItem, krate: &'ast hir::Crate) { + self.hir_crate = Some(krate); + ii.visit(self); + } + fn parent_def(&self) -> Option { self.parent_def } @@ -83,7 +97,7 @@ impl DefCollector { } } -impl<'ast> visit::Visitor<'ast> for DefCollector { +impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { fn visit_item(&mut self, i: &'ast Item) { debug!("visit_item: {:?}", i); @@ -226,3 +240,151 @@ impl<'ast> visit::Visitor<'ast> for DefCollector { self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name)); } } + +// We walk the HIR rather than the AST when reading items from metadata. +impl<'ast> intravisit::Visitor<'ast> for DefCollector<'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_id: hir::ItemId) { + debug!("visit_nested_item: {:?}", item_id); + let item = self.hir_crate.unwrap().item(item_id.id); + self.visit_item(item) + } + + fn visit_item(&mut self, i: &'ast hir::Item) { + debug!("visit_item: {:?}", i); + + // Pick the def data. This need not be unique, but the more + // information we encapsulate into + let def_data = match i.node { + hir::ItemDefaultImpl(..) | hir::ItemImpl(..) => + DefPathData::Impl, + hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemTrait(..) | + hir::ItemExternCrate(..) | hir::ItemMod(..) | hir::ItemForeignMod(..) | + hir::ItemTy(..) => + DefPathData::TypeNs(i.name), + hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => + DefPathData::ValueNs(i.name), + hir::ItemUse(..) => DefPathData::Misc, + }; + let def = self.create_def(i.id, def_data); + + self.with_parent(def, |this| { + match i.node { + hir::ItemEnum(ref enum_definition, _) => { + for v in &enum_definition.variants { + let variant_def_index = + this.create_def(v.node.data.id(), + DefPathData::EnumVariant(v.node.name)); + + for field in v.node.data.fields() { + this.create_def_with_parent(Some(variant_def_index), + field.id, + DefPathData::Field(field.name)); + } + } + } + hir::ItemStruct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + this.create_def(struct_def.id(), + DefPathData::StructCtor); + } + + for field in struct_def.fields() { + this.create_def(field.id, DefPathData::Field(field.name)); + } + } + _ => {} + } + intravisit::walk_item(this, i); + }); + } + + fn visit_foreign_item(&mut self, foreign_item: &'ast hir::ForeignItem) { + let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); + + self.with_parent(def, |this| { + intravisit::walk_foreign_item(this, foreign_item); + }); + } + + fn visit_generics(&mut self, generics: &'ast hir::Generics) { + for ty_param in generics.ty_params.iter() { + self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.name)); + } + + intravisit::walk_generics(self, generics); + } + + fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) { + let def_data = match ti.node { + hir::MethodTraitItem(..) | hir::ConstTraitItem(..) => + DefPathData::ValueNs(ti.name), + hir::TypeTraitItem(..) => DefPathData::TypeNs(ti.name), + }; + + let def = self.create_def(ti.id, def_data); + self.with_parent(def, |this| { + if let hir::ConstTraitItem(_, Some(ref expr)) = ti.node { + this.create_def(expr.id, DefPathData::Initializer); + } + + intravisit::walk_trait_item(this, ti); + }); + } + + fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) { + let def_data = match ii.node { + hir::ImplItemKind::Method(..) | hir::ImplItemKind::Const(..) => + DefPathData::ValueNs(ii.name), + hir::ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), + }; + + let def = self.create_def(ii.id, def_data); + self.with_parent(def, |this| { + if let hir::ImplItemKind::Const(_, ref expr) = ii.node { + this.create_def(expr.id, DefPathData::Initializer); + } + + intravisit::walk_impl_item(this, ii); + }); + } + + fn visit_pat(&mut self, pat: &'ast hir::Pat) { + let maybe_binding = match pat.node { + hir::PatKind::Ident(_, id, _) => Some(id.node), + _ => None + }; + + let parent_def = self.parent_def; + if let Some(id) = maybe_binding { + let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + self.parent_def = Some(def); + } + + intravisit::walk_pat(self, pat); + self.parent_def = parent_def; + } + + fn visit_expr(&mut self, expr: &'ast hir::Expr) { + let parent_def = self.parent_def; + + if let hir::ExprClosure(..) = expr.node { + let def = self.create_def(expr.id, DefPathData::ClosureExpr); + self.parent_def = Some(def); + } + + intravisit::walk_expr(self, expr); + self.parent_def = parent_def; + } + + fn visit_lifetime_def(&mut self, def: &'ast hir::LifetimeDef) { + self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); + } + + fn visit_macro_def(&mut self, macro_def: &'ast hir::MacroDef) { + self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); + } +} \ No newline at end of file diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index a505ad198896f..1d0c40646b51a 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -843,14 +843,13 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let ii = map.forest.inlined_items.alloc(ii); let ii_parent_id = fld.new_id(DUMMY_NODE_ID); - // TODO need to save defs in metadata :-( - // let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); - // let mut def_collector = DefCollector::extend(ii_parent_id, - // parent_def_path.clone(), - // parent_def_id, - // defs); - // ii.visit(&mut def_collector); - // *map.definitions.borrow_mut() = def_collector.definitions; + let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); + let mut def_collector = DefCollector::extend(ii_parent_id, + parent_def_path.clone(), + parent_def_id, + defs); + def_collector.walk_item(ii, map.krate()); + *map.definitions.borrow_mut() = def_collector.definitions; let mut collector = NodeCollector::extend(map.krate(), ii, From 1d5a29cf0e40c412bb2e090aadcf3ebfb1d5fa13 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Mon, 18 Apr 2016 10:30:55 +1200 Subject: [PATCH 8/9] debugging, misc fixes --- src/librustc/hir/lowering.rs | 218 ++++++++++++++------- src/librustc/hir/map/collector.rs | 7 +- src/librustc/hir/map/def_collector.rs | 46 ++--- src/librustc/hir/map/mod.rs | 8 +- src/librustc_driver/driver.rs | 9 +- src/librustc_driver/lib.rs | 11 +- src/librustc_driver/pretty.rs | 19 +- src/librustc_driver/test.rs | 12 +- src/librustc_metadata/astencode.rs | 8 +- src/librustc_metadata/creader.rs | 11 +- src/librustc_save_analysis/csv_dumper.rs | 4 +- src/librustc_save_analysis/dump_visitor.rs | 23 +-- src/librustc_save_analysis/lib.rs | 11 +- src/librustc_save_analysis/span_utils.rs | 2 + src/librustdoc/core.rs | 13 +- src/librustdoc/test.rs | 8 +- src/test/run-make/execution-engine/test.rs | 12 +- 17 files changed, 260 insertions(+), 162 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7c47665704118..0a01cc91f0e30 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -62,6 +62,9 @@ // in the HIR, especially for multiple identifiers. use hir; +use hir::map::Definitions; +use hir::map::definitions::DefPathData; +use hir::def_id::DefIndex; use std::collections::BTreeMap; use std::collections::HashMap; @@ -92,10 +95,20 @@ pub struct LoweringContext<'a> { // A copy of cached_id, but is also set to an id while a node is lowered for // the first time. gensym_key: Cell, + // We must keep the set of definitions up to date as we add nodes that + // weren't in the AST. + definitions: Option<&'a RefCell>, + // As we walk the AST we must keep track of the current 'parent' def id (in + // the form of a DefIndex) so that if we create a new node which introduces + // a definition, then we can properly create the def id. + parent_def: Cell>, } impl<'a, 'hir> LoweringContext<'a> { - pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>) -> LoweringContext<'a> { + pub fn new(id_assigner: &'a NodeIdAssigner, + c: Option<&Crate>, + defs: &'a RefCell) + -> LoweringContext<'a> { let crate_root = c.and_then(|c| { if std_inject::no_core(c) { None @@ -113,6 +126,23 @@ impl<'a, 'hir> LoweringContext<'a> { cached_id: Cell::new(0), gensym_cache: RefCell::new(HashMap::new()), gensym_key: Cell::new(0), + definitions: Some(defs), + parent_def: Cell::new(None), + } + } + + // Only use this when you want a LoweringContext for testing and won't look + // up def ids for anything created during lowering. + pub fn testing_context(id_assigner: &'a NodeIdAssigner) -> LoweringContext<'a> { + LoweringContext { + crate_root: None, + id_cache: RefCell::new(HashMap::new()), + id_assigner: id_assigner, + cached_id: Cell::new(0), + gensym_cache: RefCell::new(HashMap::new()), + gensym_key: Cell::new(0), + definitions: None, + parent_def: Cell::new(None), } } @@ -146,6 +176,25 @@ impl<'a, 'hir> LoweringContext<'a> { fn diagnostic(&self) -> &Handler { self.id_assigner.diagnostic() } + + fn with_parent_def T>(&self, parent_id: NodeId, f: F) -> T { + if self.definitions.is_none() { + // This should only be used for testing. + return f(); + } + + let old_def = self.parent_def.get(); + self.parent_def.set(Some(self.get_def(parent_id))); + let result = f(); + self.parent_def.set(old_def); + + result + } + + fn get_def(&self, id: NodeId) -> DefIndex { + let defs = self.definitions.unwrap().borrow(); + defs.opt_def_index(id).unwrap() + } } // Utility fn for setting and unsetting the cached id. @@ -733,47 +782,51 @@ pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ { } pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem { - hir::TraitItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - TraitItemKind::Const(ref ty, ref default) => { - hir::ConstTraitItem(lower_ty(lctx, ty), - default.as_ref().map(|x| lower_expr(lctx, x))) - } - TraitItemKind::Method(ref sig, ref body) => { - hir::MethodTraitItem(lower_method_sig(lctx, sig), - body.as_ref().map(|x| lower_block(lctx, x))) - } - TraitItemKind::Type(ref bounds, ref default) => { - hir::TypeTraitItem(lower_bounds(lctx, bounds), - default.as_ref().map(|x| lower_ty(lctx, x))) - } - }, - span: i.span, - } + lctx.with_parent_def(i.id, || { + hir::TraitItem { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + node: match i.node { + TraitItemKind::Const(ref ty, ref default) => { + hir::ConstTraitItem(lower_ty(lctx, ty), + default.as_ref().map(|x| lower_expr(lctx, x))) + } + TraitItemKind::Method(ref sig, ref body) => { + hir::MethodTraitItem(lower_method_sig(lctx, sig), + body.as_ref().map(|x| lower_block(lctx, x))) + } + TraitItemKind::Type(ref bounds, ref default) => { + 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) -> hir::ImplItem { - hir::ImplItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - vis: lower_visibility(lctx, &i.vis), - defaultness: lower_defaultness(lctx, i.defaultness), - node: match i.node { - ImplItemKind::Const(ref ty, ref 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)) - } - ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)), - ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), - }, - span: i.span, - } + lctx.with_parent_def(i.id, || { + hir::ImplItem { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + vis: lower_visibility(lctx, &i.vis), + defaultness: lower_defaultness(lctx, i.defaultness), + node: match i.node { + ImplItemKind::Const(ref ty, ref 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)) + } + 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 { @@ -831,7 +884,9 @@ pub fn lower_item_id(_lctx: &LoweringContext, i: &Item) -> hir::ItemId { } pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { - let node = lower_item_kind(lctx, &i.node); + let node = lctx.with_parent_def(i.id, || { + lower_item_kind(lctx, &i.node) + }); hir::Item { id: i.id, @@ -844,21 +899,23 @@ pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { } pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::ForeignItem { - hir::ForeignItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - ForeignItemKind::Fn(ref fdec, ref generics) => { - hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics)) - } - ForeignItemKind::Static(ref t, m) => { - hir::ForeignItemStatic(lower_ty(lctx, t), m) - } - }, - vis: lower_visibility(lctx, &i.vis), - span: i.span, - } + lctx.with_parent_def(i.id, || { + hir::ForeignItem { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + node: match i.node { + ForeignItemKind::Fn(ref fdec, ref generics) => { + hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics)) + } + ForeignItemKind::Static(ref t, m) => { + hir::ForeignItemStatic(lower_ty(lctx, t), m) + } + }, + vis: lower_visibility(lctx, &i.vis), + span: i.span, + } + }) } pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig { @@ -926,9 +983,11 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { node: match p.node { PatKind::Wild => hir::PatKind::Wild, PatKind::Ident(ref binding_mode, pth1, ref sub) => { - hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), - respan(pth1.span, lower_ident(lctx, pth1.node)), - sub.as_ref().map(|x| lower_pat(lctx, x))) + lctx.with_parent_def(p.id, || { + hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), + respan(pth1.span, lower_ident(lctx, pth1.node)), + sub.as_ref().map(|x| lower_pat(lctx, x))) + }) } PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)), PatKind::TupleStruct(ref pth, ref pats) => { @@ -1202,9 +1261,11 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { hir::MatchSource::Normal) } ExprKind::Closure(capture_clause, ref decl, ref body) => { - hir::ExprClosure(lower_capture_clause(lctx, capture_clause), - lower_fn_decl(lctx, decl), - lower_block(lctx, body)) + lctx.with_parent_def(e.id, || { + hir::ExprClosure(lower_capture_clause(lctx, capture_clause), + lower_fn_decl(lctx, decl), + lower_block(lctx, body)) + }) } ExprKind::Block(ref blk) => hir::ExprBlock(lower_block(lctx, blk)), ExprKind::Assign(ref el, ref er) => { @@ -1602,7 +1663,12 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { // `{ let _result = ...; _result }` // underscore prevents an unused_variables lint if the head diverges let result_ident = lctx.str_to_ident("_result"); - let let_stmt = stmt_let(lctx, e.span, false, result_ident, match_expr, None); + let let_stmt = stmt_let(lctx, + e.span, + false, + result_ident, + match_expr, + None); let result = expr_ident(lctx, e.span, result_ident, None); let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result)); // add the attributes to the outer returned expr node @@ -1655,7 +1721,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { let err_ctor = expr_path(lctx, path, None); expr_call(lctx, e.span, err_ctor, hir_vec![from_expr], None) }; - let err_pat = pat_err(lctx, e.span, pat_ident(lctx, e.span, err_ident)); + let err_pat = pat_err(lctx, e.span, + pat_ident(lctx, e.span, err_ident)); let ret_expr = expr(lctx, e.span, hir::Expr_::ExprRet(Some(err_expr)), None); @@ -1938,12 +2005,22 @@ fn pat_ident_binding_mode(lctx: &LoweringContext, bm: hir::BindingMode) -> P { let pat_ident = hir::PatKind::Ident(bm, - Spanned { - span: span, - node: ident, - }, - None); - pat(lctx, span, pat_ident) + Spanned { + span: span, + node: ident, + }, + None); + + let pat = pat(lctx, span, pat_ident); + + if let Some(defs) = lctx.definitions { + let mut defs = defs.borrow_mut(); + defs.create_def_with_parent(lctx.parent_def.get(), + pat.id, + DefPathData::Binding(ident.name)); + } + + pat } fn pat_wild(lctx: &LoweringContext, span: Span) -> P { @@ -2130,7 +2207,8 @@ mod test { let ast_in = quote_expr!(&cx, in HEAP { foo() }); let ast_in = assigner.fold_expr(ast_in); - let lctx = LoweringContext::new(&assigner, None); + let lctx = LoweringContext::testing_context(&assigner); + let hir1 = lower_expr(&lctx, &ast_if_let); let hir2 = lower_expr(&lctx, &ast_if_let); assert!(hir1 == hir2); diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index c9d93319c03a8..9f55f46541cfd 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -162,7 +162,12 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } fn visit_pat(&mut self, pat: &'ast Pat) { - self.insert(pat.id, NodeLocal(pat)); + let node = if let PatKind::Ident(..) = pat.node { + NodeLocal(pat) + } else { + NodePat(pat) + }; + self.insert(pat.id, node); self.with_parent(pat.id, |this| { intravisit::walk_pat(this, pat); diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index f8d0243548fd1..b2456f4ab8714 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -18,6 +18,7 @@ use middle::cstore::InlinedItem; use syntax::ast::*; use syntax::visit; +use syntax::parse::token; /// Creates def ids for nodes in the HIR. pub struct DefCollector<'ast> { @@ -35,8 +36,9 @@ impl<'ast> DefCollector<'ast> { definitions: Definitions::new(), parent_def: None, }; - let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); - assert_eq!(result, CRATE_DEF_INDEX); + let root = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); + assert_eq!(root, CRATE_DEF_INDEX); + collector.parent_def = Some(root); collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc); @@ -125,12 +127,12 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { this.create_def(v.node.data.id(), DefPathData::EnumVariant(v.node.name.name)); - for field in v.node.data.fields() { - if let Some(ident) = field.ident { - this.create_def_with_parent(Some(variant_def_index), - field.id, - DefPathData::Field(ident.name)); - } + for (index, field) in v.node.data.fields().iter().enumerate() { + let name = field.ident.map(|ident| ident.name) + .unwrap_or(token::intern(&index.to_string())); + this.create_def_with_parent(Some(variant_def_index), + field.id, + DefPathData::Field(name)); } } } @@ -141,10 +143,10 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { DefPathData::StructCtor); } - for field in struct_def.fields() { - if let Some(ident) = field.ident { - this.create_def(field.id, DefPathData::Field(ident.name)); - } + for (index, field) in struct_def.fields().iter().enumerate() { + let name = field.ident.map(|ident| ident.name) + .unwrap_or(token::intern(&index.to_string())); + this.create_def(field.id, DefPathData::Field(name)); } } _ => {} @@ -205,14 +207,10 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { } fn visit_pat(&mut self, pat: &'ast Pat) { - let maybe_binding = match pat.node { - PatKind::Ident(_, id, _) => Some(id.node), - _ => None - }; - let parent_def = self.parent_def; - if let Some(id) = maybe_binding { - let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + + if let PatKind::Ident(_, id, _) = pat.node { + let def = self.create_def(pat.id, DefPathData::Binding(id.node.name)); self.parent_def = Some(def); } @@ -353,14 +351,10 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> { } fn visit_pat(&mut self, pat: &'ast hir::Pat) { - let maybe_binding = match pat.node { - hir::PatKind::Ident(_, id, _) => Some(id.node), - _ => None - }; - let parent_def = self.parent_def; - if let Some(id) = maybe_binding { - let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + + if let hir::PatKind::Ident(_, id, _) = pat.node { + let def = self.create_def(pat.id, DefPathData::Binding(id.node.name)); self.parent_def = Some(def); } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 1d0c40646b51a..92f8c9249c842 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -196,7 +196,7 @@ pub struct Map<'ast> { /// plain old integers. map: RefCell>>, - definitions: RefCell, + definitions: &'ast RefCell, } impl<'ast> Map<'ast> { @@ -789,7 +789,9 @@ pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions { def_collector.definitions } -pub fn map_crate<'ast>(forest: &'ast mut Forest, definitions: Definitions) -> Map<'ast> { +pub fn map_crate<'ast>(forest: &'ast mut Forest, + definitions: &'ast RefCell) + -> Map<'ast> { let mut collector = NodeCollector::root(&forest.krate); intravisit::walk_crate(&mut collector, &forest.krate); let map = collector.map; @@ -814,7 +816,7 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest, definitions: Definitions) -> Ma forest: forest, dep_graph: forest.dep_graph.clone(), map: RefCell::new(map), - definitions: RefCell::new(definitions), + definitions: definitions, } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 6724c0ed8ebfd..26422e3194a22 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -43,6 +43,7 @@ use super::Compilation; use serialize::json; +use std::cell::RefCell; use std::collections::HashMap; use std::env; use std::ffi::{OsString, OsStr}; @@ -123,9 +124,9 @@ pub fn compile_input(sess: &Session, let dep_graph = DepGraph::new(sess.opts.build_dep_graph); // Collect defintions for def ids. - let defs = time(sess.time_passes(), - "collecting defs", - || hir_map::collect_definitions(&expanded_crate)); + let defs = &RefCell::new(time(sess.time_passes(), + "collecting defs", + || hir_map::collect_definitions(&expanded_crate))); time(sess.time_passes(), "external crate/lib resolution", @@ -133,7 +134,7 @@ pub fn compile_input(sess: &Session, .read_crates(&dep_graph)); // Lower ast -> hir. - let lcx = LoweringContext::new(sess, Some(&expanded_crate)); + let lcx = LoweringContext::new(sess, Some(&expanded_crate), defs); let hir_forest = &mut time(sess.time_passes(), "lowering ast -> hir", || hir_map::Forest::new(lower_crate(&lcx, &expanded_crate), diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 769449b96d2b1..0e100f48ac38d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -199,14 +199,9 @@ pub fn run_compiler<'a>(args: &[String], // It is somewhat unfortunate that this is hardwired in - this is forced by // the fact that pretty_print_input requires the session by value. let pretty = callbacks.parse_pretty(&sess, &matches); - match pretty { - Some((ppm, opt_uii)) => { - pretty::pretty_print_input(sess, &cstore, cfg, &input, ppm, opt_uii, ofile); - return (Ok(()), None); - } - None => { - // continue - } + if let Some((ppm, opt_uii)) = pretty { + pretty::pretty_print_input(sess, &cstore, cfg, &input, ppm, opt_uii, ofile); + return (Ok(()), None); } let plugins = sess.opts.debugging_opts.extra_plugins.clone(); diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 2e3a477e04840..b1143fd3e8454 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -29,6 +29,7 @@ use rustc_borrowck as borrowck; use rustc_borrowck::graphviz as borrowck_dot; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; +use rustc_metadata::creader::LocalCrateReader; use rustc_mir::pretty::write_mir_pretty; use rustc_mir::graphviz::write_mir_graphviz; @@ -43,6 +44,7 @@ use syntax::util::small_vector::SmallVector; use graphviz as dot; +use std::cell::RefCell; use std::fs::File; use std::io::{self, Write}; use std::iter; @@ -719,7 +721,7 @@ pub fn pretty_print_input(sess: Session, let is_expanded = needs_expansion(&ppm); let compute_ast_map = needs_ast_map(&ppm, &opt_uii); let krate = if compute_ast_map { - match driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id[..], None) { + match driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None) { Err(_) => return, Ok(k) => driver::assign_node_ids(&sess, k), } @@ -730,15 +732,18 @@ pub fn pretty_print_input(sess: Session, // There is some twisted, god-forsaken tangle of lifetimes here which makes // the ordering of stuff super-finicky. let mut hir_forest; - let lcx = LoweringContext::new(&sess, Some(&krate)); - let arenas = ty::CtxtArenas::new(); + let mut _defs = None; let dep_graph = DepGraph::new(false); + let arenas = ty::CtxtArenas::new(); let _ignore = dep_graph.in_ignore(); let ast_map = if compute_ast_map { - let defs = hir_map::collect_definitions(&krate); + _defs = Some(RefCell::new(hir_map::collect_definitions(&krate))); + let defs = _defs.as_ref().unwrap(); + LocalCrateReader::new(&sess, &cstore, defs, &krate, &id).read_crates(&dep_graph); + let lcx = LoweringContext::new(&sess, Some(&krate), defs); + hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); - let map = hir_map::map_crate(&mut hir_forest, defs); - Some(map) + Some(hir_map::map_crate(&mut hir_forest, defs)) } else { None }; @@ -751,7 +756,7 @@ pub fn pretty_print_input(sess: Session, .unwrap() .as_bytes() .to_vec(); - let mut rdr = &src[..]; + let mut rdr = &*src; let mut out = Vec::new(); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index fc12d546288b4..ce92dd158c969 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -27,8 +27,10 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::relate::TypeRelation; use rustc::infer::{self, InferOk, InferResult, TypeOrigin}; use rustc_metadata::cstore::CStore; +use rustc_metadata::creader::LocalCrateReader; use rustc::hir::map as hir_map; use rustc::session::{self, config}; +use std::cell::RefCell; use std::rc::Rc; use syntax::ast; use syntax::abi::Abi; @@ -119,13 +121,15 @@ fn test_env(source_string: &str, let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, "test", None) .expect("phase 2 aborted"); - let krate = driver::assign_node_ids(&sess, krate); - let lcx = LoweringContext::new(&sess, Some(&krate)); let dep_graph = DepGraph::new(false); + let krate = driver::assign_node_ids(&sess, krate); + let defs = &RefCell::new(hir_map::collect_definitions(&krate)); + LocalCrateReader::new(&sess, &cstore, defs, &krate, "test_crate").read_crates(&dep_graph); + let lcx = LoweringContext::new(&sess, Some(&krate), defs); let _ignore = dep_graph.in_ignore(); - let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); + let mut hir_forest = &mut hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); let arenas = ty::CtxtArenas::new(); - let ast_map = driver::make_map(&sess, &mut hir_forest); + let ast_map = hir_map::map_crate(hir_forest, defs); // run just enough stuff to build a tcx: let lang_items = lang_items::collect_language_items(&sess, &ast_map); diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 49512a5018e7d..2d6a043e34aeb 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -1339,7 +1339,7 @@ fn roundtrip(in_item: hir::Item) { fn test_basic() { let cx = mk_ctxt(); let fnia = FakeNodeIdAssigner; - let lcx = LoweringContext::new(&fnia, None); + let lcx = LoweringContext::testing_context(&fnia); roundtrip(lower_item(&lcx, "e_item!(&cx, fn foo() {} ).unwrap())); @@ -1349,7 +1349,7 @@ fn test_basic() { fn test_smalltalk() { let cx = mk_ctxt(); let fnia = FakeNodeIdAssigner; - let lcx = LoweringContext::new(&fnia, None); + let lcx = LoweringContext::testing_context(&fnia); roundtrip(lower_item(&lcx, "e_item!(&cx, fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed. ).unwrap())); @@ -1359,7 +1359,7 @@ fn test_smalltalk() { fn test_more() { let cx = mk_ctxt(); let fnia = FakeNodeIdAssigner; - let lcx = LoweringContext::new(&fnia, None); + let lcx = LoweringContext::testing_context(&fnia); roundtrip(lower_item(&lcx, "e_item!(&cx, fn foo(x: usize, y: usize) -> usize { let z = x + y; @@ -1378,7 +1378,7 @@ fn test_simplification() { } ).unwrap(); let fnia = FakeNodeIdAssigner; - let lcx = LoweringContext::new(&fnia, None); + let lcx = LoweringContext::testing_context(&fnia); let hir_item = lower_item(&lcx, &item); let item_in = InlinedItemRef::Item(&hir_item); let item_out = simplify_ast(item_in); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 4ba59a3d7ebe9..635ef4ab35836 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -45,7 +45,7 @@ pub struct LocalCrateReader<'a> { cstore: &'a CStore, creader: CrateReader<'a>, krate: &'a ast::Crate, - defintions: &'a hir_map::Definitions, + defintions: &'a RefCell, } pub struct CrateReader<'a> { @@ -59,6 +59,7 @@ pub struct CrateReader<'a> { impl<'a, 'ast> visit::Visitor<'ast> for LocalCrateReader<'a> { fn visit_item(&mut self, a: &'ast ast::Item) { self.process_item(a); + visit::walk_item(self, a); } } @@ -81,6 +82,7 @@ fn should_link(i: &ast::Item) -> bool { !attr::contains_name(&i.attrs, "no_link") } +#[derive(Debug)] struct CrateInfo { ident: String, name: String, @@ -750,7 +752,7 @@ impl<'a> CrateReader<'a> { impl<'a> LocalCrateReader<'a> { pub fn new(sess: &'a Session, cstore: &'a CStore, - defs: &'a hir_map::Definitions, + defs: &'a RefCell, krate: &'a ast::Crate, local_crate_name: &str) -> LocalCrateReader<'a> { @@ -807,9 +809,10 @@ impl<'a> LocalCrateReader<'a> { i.span, PathKind::Crate, true); - let def_id = self.defintions.opt_local_def_id(i.id).unwrap(); - let len = self.defintions.def_path(def_id.index).data.len(); + let defs = self.defintions.borrow(); + let def_id = defs.opt_local_def_id(i.id).unwrap(); + let len = defs.def_path(def_id.index).data.len(); self.creader.update_extern_crate(cnum, ExternCrate { diff --git a/src/librustc_save_analysis/csv_dumper.rs b/src/librustc_save_analysis/csv_dumper.rs index 0e02830db7ad7..45ec9a97a1184 100644 --- a/src/librustc_save_analysis/csv_dumper.rs +++ b/src/librustc_save_analysis/csv_dumper.rs @@ -17,10 +17,10 @@ use super::data::*; use super::dump::Dump; use super::span_utils::SpanUtils; -pub struct CsvDumper<'a, 'b, W: 'b> { +pub struct CsvDumper<'tcx, 'b, W: 'b> { output: &'b mut W, dump_spans: bool, - span: SpanUtils<'a> + span: SpanUtils<'tcx> } impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 3784c95fe2bcb..bf6ad7039636e 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -42,7 +42,7 @@ use syntax::visit::{self, Visitor}; use syntax::print::pprust::{path_to_string, ty_to_string}; use syntax::ptr::P; -use rustc::hir::lowering::{lower_expr, LoweringContext}; +use rustc::hir::lowering::lower_expr; use super::{escape, generated_code, SaveContext, PathCollector}; use super::data::*; @@ -60,12 +60,12 @@ macro_rules! down_cast_data { }; } -pub struct DumpVisitor<'l, 'tcx: 'l, D: 'l> { +pub struct DumpVisitor<'l, 'tcx: 'l, 'll, D: 'll> { save_ctxt: SaveContext<'l, 'tcx>, sess: &'l Session, tcx: &'l TyCtxt<'tcx>, analysis: &'l ty::CrateAnalysis<'l>, - dumper: &'l mut D, + dumper: &'ll mut D, span: SpanUtils<'l>, @@ -77,22 +77,19 @@ pub struct DumpVisitor<'l, 'tcx: 'l, D: 'l> { // one macro use per unique callsite span. mac_defs: HashSet, mac_uses: HashSet, - } -impl <'l, 'tcx, D> DumpVisitor<'l, 'tcx, D> -where D: Dump -{ +impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { pub fn new(tcx: &'l TyCtxt<'tcx>, - lcx: &'l LoweringContext<'l>, + save_ctxt: SaveContext<'l, 'tcx>, analysis: &'l ty::CrateAnalysis<'l>, - dumper: &'l mut D) - -> DumpVisitor<'l, 'tcx, D> { + dumper: &'ll mut D) + -> DumpVisitor<'l, 'tcx, 'll, D> { let span_utils = SpanUtils::new(&tcx.sess); DumpVisitor { sess: &tcx.sess, tcx: tcx, - save_ctxt: SaveContext::from_span_utils(tcx, lcx, span_utils.clone()), + save_ctxt: save_ctxt, analysis: analysis, dumper: dumper, span: span_utils.clone(), @@ -103,7 +100,7 @@ where D: Dump } fn nest(&mut self, scope_id: NodeId, f: F) - where F: FnOnce(&mut DumpVisitor<'l, 'tcx, D>) + where F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, D>) { let parent_scope = self.cur_scope; self.cur_scope = scope_id; @@ -982,7 +979,7 @@ where D: Dump } } -impl<'l, 'tcx, 'v, D: Dump + 'l> Visitor<'v> for DumpVisitor<'l, 'tcx, D> { +impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx, 'll, D> { fn visit_item(&mut self, item: &ast::Item) { use syntax::ast::ItemKind::*; self.process_macro_use(item.span, item.id); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 4596398c3152e..9148b53322bfe 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -73,7 +73,7 @@ pub mod recorder { pub struct SaveContext<'l, 'tcx: 'l> { tcx: &'l TyCtxt<'tcx>, lcx: &'l lowering::LoweringContext<'l>, - span_utils: SpanUtils<'l>, + span_utils: SpanUtils<'tcx>, } macro_rules! option_try( @@ -90,7 +90,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn from_span_utils(tcx: &'l TyCtxt<'tcx>, lcx: &'l lowering::LoweringContext<'l>, - span_utils: SpanUtils<'l>) + span_utils: SpanUtils<'tcx>) -> SaveContext<'l, 'tcx> { SaveContext { tcx: tcx, @@ -680,7 +680,7 @@ impl<'v> Visitor<'v> for PathCollector { pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>, lcx: &'l lowering::LoweringContext<'l>, krate: &ast::Crate, - analysis: &ty::CrateAnalysis, + analysis: &'l ty::CrateAnalysis<'l>, cratename: &str, odir: Option<&Path>) { let _ignore = tcx.dep_graph.in_ignore(); @@ -726,9 +726,10 @@ pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>, }); root_path.pop(); - let utils = SpanUtils::new(&tcx.sess); + let utils: SpanUtils<'tcx> = SpanUtils::new(&tcx.sess); + let save_ctxt = SaveContext::new(tcx, lcx); let mut dumper = CsvDumper::new(&mut output_file, utils); - let mut visitor = DumpVisitor::new(tcx, lcx, analysis, &mut dumper); + let mut visitor = DumpVisitor::new(tcx, save_ctxt, analysis, &mut dumper); // FIXME: we don't write anything! visitor.dump_crate_info(cratename, krate); diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index f410d428177cd..c64eeb92737e0 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -26,6 +26,8 @@ use syntax::parse::token::{keywords, Token}; #[derive(Clone)] pub struct SpanUtils<'a> { pub sess: &'a Session, + // FIXME given that we clone SpanUtils all over the place, this err_count is + // probably useless and any logic relying on it is bogus. pub err_count: Cell, } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b7c60b8a524c0..6d1e91a687e58 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -22,6 +22,7 @@ use rustc_trans::back::link; use rustc_resolve as resolve; use rustc::hir::lowering::{lower_crate, LoweringContext}; use rustc_metadata::cstore::CStore; +use rustc_metadata::creader::LocalCrateReader; use syntax::{ast, codemap, errors}; use syntax::errors::emitter::ColorConfig; @@ -151,14 +152,18 @@ pub fn run_core(search_paths: SearchPaths, .expect("phase_2_configure_and_expand aborted in rustdoc!"); let krate = driver::assign_node_ids(&sess, krate); + let dep_graph = DepGraph::new(false); + + let defs = &RefCell::new(hir_map::collect_definitions(&krate)); + LocalCrateReader::new(&sess, &cstore, &defs, &krate, &name).read_crates(&dep_graph); + let lcx = LoweringContext::new(&sess, Some(&krate), defs); + // Lower ast -> hir. - let lcx = LoweringContext::new(&sess, Some(&krate)); - let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), DepGraph::new(false)); + let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph); let arenas = ty::CtxtArenas::new(); - let hir_map = driver::make_map(&sess, &mut hir_forest); + let hir_map = hir_map::map_crate(&mut hir_forest, defs); abort_on_err(driver::phase_3_run_analysis_passes(&sess, - &cstore, hir_map, &arenas, &name, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 5a7050fb42f30..487aac1806ea7 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -94,15 +94,17 @@ pub fn run(input: &str, "rustdoc-test", None) .expect("phase_2_configure_and_expand aborted in rustdoc!"); let krate = driver::assign_node_ids(&sess, krate); - let lcx = LoweringContext::new(&sess, Some(&krate)); + let dep_graph = DepGraph::new(false); + let defs = &RefCell::new(hir_map::collect_definitions(&krate)); + + let lcx = LoweringContext::new(&sess, Some(&krate), defs); let krate = lower_crate(&lcx, &krate); let opts = scrape_test_config(&krate); - let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); let mut forest = hir_map::Forest::new(krate, dep_graph.clone()); - let map = hir_map::map_crate(&mut forest); + let map = hir_map::map_crate(&mut forest, defs); let ctx = core::DocContext { map: &map, diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index 12cc475f121f6..86b9c4c81c66b 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -20,6 +20,7 @@ extern crate rustc_metadata; extern crate rustc_resolve; #[macro_use] extern crate syntax; +use std::cell::RefCell; use std::ffi::{CStr, CString}; use std::mem::transmute; use std::path::PathBuf; @@ -35,6 +36,7 @@ use rustc::session::build_session; use rustc_driver::{driver, abort_on_err}; use rustc::hir::lowering::{lower_crate, LoweringContext}; use rustc_resolve::MakeGlobMap; +use rustc_metadata::creader::LocalCrateReader; use rustc_metadata::cstore::CStore; use libc::c_void; @@ -237,15 +239,17 @@ fn compile_program(input: &str, sysroot: PathBuf) let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None) .expect("phase_2 returned `None`"); + let dep_graph = DepGraph::new(sess.opts.build_dep_graph); let krate = driver::assign_node_ids(&sess, krate); - let lcx = LoweringContext::new(&sess, Some(&krate)); - let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); + let defs = RefCell::new(ast_map::collect_definitions(&krate)); + LocalCrateReader::new(&sess, &cstore, &defs, &krate, &id).read_crates(&dep_graph); + let lcx = LoweringContext::new(&sess, Some(&krate), &defs); let mut hir_forest = ast_map::Forest::new(lower_crate(&lcx, &krate), dep_graph); let arenas = ty::CtxtArenas::new(); - let ast_map = driver::make_map(&sess, &mut hir_forest); + let ast_map = ast_map::map_crate(&mut hir_forest, &defs); abort_on_err(driver::phase_3_run_analysis_passes( - &sess, &cstore, ast_map, &arenas, &id, + &sess, ast_map, &arenas, &id, MakeGlobMap::No, |tcx, mir_map, analysis, _| { let trans = driver::phase_4_translate_to_llvm(tcx, mir_map.unwrap(), analysis); From 0be3c8c56977c1f0d875461279e00bca7b4e5ebf Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 19 Apr 2016 16:16:40 +1200 Subject: [PATCH 9/9] rebasing --- src/librustc/hir/map/def_collector.rs | 4 ++-- src/librustc_driver/driver.rs | 2 +- src/test/run-make/execution-engine/test.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index b2456f4ab8714..053d32305be03 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -109,9 +109,9 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => DefPathData::Impl, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Trait(..) | - ItemKind::ExternCrate(..) | ItemKind::Mod(..) | ItemKind::ForeignMod(..) | - ItemKind::Ty(..) => + ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.name), + ItemKind::Mod(..) => DefPathData::Module(i.ident.name), ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => DefPathData::ValueNs(i.ident.name), ItemKind::Mac(..) => DefPathData::MacroDef(i.ident.name), diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 26422e3194a22..5fc2a955c0602 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -121,7 +121,7 @@ pub fn compile_input(sess: &Session, Ok(())); let expanded_crate = assign_node_ids(sess, expanded_crate); - let dep_graph = DepGraph::new(sess.opts.build_dep_graph); + let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); // Collect defintions for def ids. let defs = &RefCell::new(time(sess.time_passes(), diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index 86b9c4c81c66b..b9a45c09626a7 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -239,7 +239,7 @@ fn compile_program(input: &str, sysroot: PathBuf) let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None) .expect("phase_2 returned `None`"); - let dep_graph = DepGraph::new(sess.opts.build_dep_graph); + let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); let krate = driver::assign_node_ids(&sess, krate); let defs = RefCell::new(ast_map::collect_definitions(&krate)); LocalCrateReader::new(&sess, &cstore, &defs, &krate, &id).read_crates(&dep_graph);