From f61b40446777f9ef9b32c19d8df24ded855fd082 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 11:55:34 +1200 Subject: [PATCH] Split up NodeCollector so that defs are collected separately from nodes for the HIR map. --- src/librustc/hir/map/collector.rs | 335 ++++++++++++++++++++---------- src/librustc/hir/map/mod.rs | 38 ++-- src/librustc_driver/driver.rs | 37 ++-- 3 files changed, 269 insertions(+), 141 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 95f9e8eaac2..7f6a587fade 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 { - krate: krate, - map: vec![], - definitions: Definitions::new(), - parent_node: CRATE_NODE_ID, - }; - collector.insert_entry(CRATE_NODE_ID, RootCrate); +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); @@ -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,6 +153,196 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { 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 { + 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 { @@ -206,9 +367,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { - self.insert_def(foreign_item.id, - NodeForeignItem(foreign_item), - DefPathData::ValueNs(foreign_item.name)); + self.insert(foreign_item.id, NodeForeignItem(foreign_item)); let parent_node = self.parent_node; self.parent_node = foreign_item.id; @@ -218,72 +377,36 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { 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), - DefPathData::TypeParam(ty_param.name)); + self.insert(ty_param.id, NodeTyParam(ty_param)); } 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), - }; - self.insert(ti.id, NodeTraitItem(ti)); - self.create_def(ti.id, def_data); let parent_node = self.parent_node; self.parent_node = ti.id; - match ti.node { - ConstTraitItem(_, Some(ref expr)) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - intravisit::walk_trait_item(self, ti); self.parent_node = parent_node; } 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), - }; - - self.insert_def(ii.id, NodeImplItem(ii), def_data); + self.insert(ii.id, NodeImplItem(ii)); let parent_node = self.parent_node; self.parent_node = ii.id; - match ii.node { - ImplItemKind::Const(_, ref expr) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - intravisit::walk_impl_item(self, ii); self.parent_node = parent_node; } fn visit_pat(&mut self, pat: &'ast Pat) { - let maybe_binding = match pat.node { - PatKind::Ident(_, id, _) => Some(id.node), - _ => None - }; - - if let Some(id) = maybe_binding { - self.insert_def(pat.id, NodeLocal(pat), DefPathData::Binding(id.name)); - } else { - self.insert(pat.id, NodePat(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 7b8ddee0e23..6331f7d3009 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 9c444fca9a1..c211fa2925e 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)