about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2016-04-14 11:55:34 +1200
committerNick Cameron <ncameron@mozilla.com>2016-04-20 10:13:35 +1200
commitf61b40446777f9ef9b32c19d8df24ded855fd082 (patch)
tree6463a92ba6ed17893a4772e36d389d1da5d910ad /src
parentc99b73a767a38d5b97214b7dbf6ee3c08ac782fd (diff)
downloadrust-f61b40446777f9ef9b32c19d8df24ded855fd082.tar.gz
rust-f61b40446777f9ef9b32c19d8df24ded855fd082.zip
Split up NodeCollector so that defs are collected separately from nodes for the HIR map.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/hir/map/collector.rs323
-rw-r--r--src/librustc/hir/map/mod.rs38
-rw-r--r--src/librustc_driver/driver.rs37
3 files changed, 263 insertions, 135 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<MapEntry<'ast>>,
-    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<DefIndex>,
+}
+
+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<MapEntry<'ast>>,
+                  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<DefIndex> {
-        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<MapEntry<'ast>>)
+                  -> 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 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<R, usize>
     where F: FnOnce(&TyCtxt<'tcx>, Option<MirMap<'tcx>>, 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)