about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-23 21:13:59 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-27 06:43:51 +0000
commitd854c362feb29125deebac562ec49da0eb3866bc (patch)
tree45c32d6ed7f46229dc982a9683b778c6ccc1e4bb
parentf34e49dd90603337da2347fe81e4d3158ae5fbd1 (diff)
downloadrust-d854c362feb29125deebac562ec49da0eb3866bc.tar.gz
rust-d854c362feb29125deebac562ec49da0eb3866bc.zip
Fix def id collection for `const_integer`s in the AST.
-rw-r--r--src/librustc/hir/map/def_collector.rs49
-rw-r--r--src/librustc/hir/map/mod.rs2
-rw-r--r--src/librustc_resolve/macros.rs23
3 files changed, 46 insertions, 28 deletions
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index 1fb078ec325..c0f38061a0d 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -27,7 +27,13 @@ pub struct DefCollector<'a> {
     hir_crate: Option<&'a hir::Crate>,
     definitions: &'a mut Definitions,
     parent_def: Option<DefIndex>,
-    pub visit_macro_invoc: Option<&'a mut FnMut(NodeId, DefIndex)>,
+    pub visit_macro_invoc: Option<&'a mut FnMut(MacroInvocationData)>,
+}
+
+pub struct MacroInvocationData {
+    pub id: NodeId,
+    pub def_index: DefIndex,
+    pub const_integer: bool,
 }
 
 impl<'a> DefCollector<'a> {
@@ -93,16 +99,15 @@ impl<'a> DefCollector<'a> {
         self.parent_def = parent;
     }
 
-    fn visit_ast_const_integer(&mut self, expr: &Expr) {
-        // Find the node which will be used after lowering.
-        if let ExprKind::Paren(ref inner) = expr.node {
-            return self.visit_ast_const_integer(inner);
-        }
-
-        // FIXME(eddyb) Closures should have separate
-        // function definition IDs and expression IDs.
-        if let ExprKind::Closure(..) = expr.node {
-            return;
+    pub fn visit_ast_const_integer(&mut self, expr: &Expr) {
+        match expr.node {
+            // Find the node which will be used after lowering.
+            ExprKind::Paren(ref inner) => return self.visit_ast_const_integer(inner),
+            ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, true),
+            // FIXME(eddyb) Closures should have separate
+            // function definition IDs and expression IDs.
+            ExprKind::Closure(..) => return,
+            _ => {}
         }
 
         self.create_def(expr.id, DefPathData::Initializer);
@@ -118,9 +123,13 @@ impl<'a> DefCollector<'a> {
         self.create_def(expr.id, DefPathData::Initializer);
     }
 
-    fn visit_macro_invoc(&mut self, id: NodeId) {
+    fn visit_macro_invoc(&mut self, id: NodeId, const_integer: bool) {
         if let Some(ref mut visit) = self.visit_macro_invoc {
-            visit(id, self.parent_def.unwrap());
+            visit(MacroInvocationData {
+                id: id,
+                const_integer: const_integer,
+                def_index: self.parent_def.unwrap(),
+            })
         }
     }
 }
@@ -144,7 +153,7 @@ impl<'a> visit::Visitor for DefCollector<'a> {
             ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
                 DefPathData::ValueNs(i.ident.name.as_str()),
             ItemKind::Mac(..) if i.id == DUMMY_NODE_ID => return, // Scope placeholder
-            ItemKind::Mac(..) => return self.visit_macro_invoc(i.id),
+            ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false),
             ItemKind::Use(..) => DefPathData::Misc,
         };
         let def = self.create_def(i.id, def_data);
@@ -210,7 +219,7 @@ impl<'a> visit::Visitor for DefCollector<'a> {
             TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
                 DefPathData::ValueNs(ti.ident.name.as_str()),
             TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name.as_str()),
-            TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id),
+            TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
         };
 
         let def = self.create_def(ti.id, def_data);
@@ -228,7 +237,7 @@ impl<'a> visit::Visitor for DefCollector<'a> {
             ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
                 DefPathData::ValueNs(ii.ident.name.as_str()),
             ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name.as_str()),
-            ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
+            ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false),
         };
 
         let def = self.create_def(ii.id, def_data);
@@ -245,7 +254,7 @@ impl<'a> visit::Visitor for DefCollector<'a> {
         let parent_def = self.parent_def;
 
         match pat.node {
-            PatKind::Mac(..) => return self.visit_macro_invoc(pat.id),
+            PatKind::Mac(..) => return self.visit_macro_invoc(pat.id, false),
             PatKind::Ident(_, id, _) => {
                 let def = self.create_def(pat.id, DefPathData::Binding(id.node.name.as_str()));
                 self.parent_def = Some(def);
@@ -261,7 +270,7 @@ impl<'a> visit::Visitor for DefCollector<'a> {
         let parent_def = self.parent_def;
 
         match expr.node {
-            ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
+            ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, false),
             ExprKind::Repeat(_, ref count) => self.visit_ast_const_integer(count),
             ExprKind::Closure(..) => {
                 let def = self.create_def(expr.id, DefPathData::ClosureExpr);
@@ -276,7 +285,7 @@ impl<'a> visit::Visitor for DefCollector<'a> {
 
     fn visit_ty(&mut self, ty: &Ty) {
         match ty.node {
-            TyKind::Mac(..) => return self.visit_macro_invoc(ty.id),
+            TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false),
             TyKind::FixedLengthVec(_, ref length) => self.visit_ast_const_integer(length),
             TyKind::ImplTrait(..) => {
                 self.create_def(ty.id, DefPathData::ImplTrait);
@@ -296,7 +305,7 @@ impl<'a> visit::Visitor for DefCollector<'a> {
 
     fn visit_stmt(&mut self, stmt: &Stmt) {
         match stmt.node {
-            StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id),
+            StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id, false),
             _ => visit::walk_stmt(self, stmt),
         }
     }
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index cd085177ed7..bafb00edc19 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -11,7 +11,7 @@
 pub use self::Node::*;
 use self::MapEntry::*;
 use self::collector::NodeCollector;
-pub use self::def_collector::DefCollector;
+pub use self::def_collector::{DefCollector, MacroInvocationData};
 pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
                             DisambiguatedDefPathData, InlinedRootPath};
 
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 1f721541ff8..17f2dff28c3 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -11,7 +11,7 @@
 use {Module, Resolver};
 use build_reduced_graph::BuildReducedGraphVisitor;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
-use rustc::hir::map::DefCollector;
+use rustc::hir::map::{self, DefCollector};
 use std::rc::Rc;
 use syntax::ast;
 use syntax::errors::DiagnosticBuilder;
@@ -27,6 +27,9 @@ use syntax::util::lev_distance::find_best_match_for_name;
 pub struct ExpansionData<'a> {
     pub module: Module<'a>,
     def_index: DefIndex,
+    // True if this expansion is in a `const_integer` position, for example `[u32; m!()]`.
+    // c.f. `DefCollector::visit_ast_const_integer`.
+    const_integer: bool,
 }
 
 impl<'a> ExpansionData<'a> {
@@ -34,6 +37,7 @@ impl<'a> ExpansionData<'a> {
         ExpansionData {
             module: graph_root,
             def_index: CRATE_DEF_INDEX,
+            const_integer: false,
         }
     }
 }
@@ -49,6 +53,7 @@ impl<'a> base::Resolver for Resolver<'a> {
         self.expansion_data.insert(mark.as_u32(), ExpansionData {
             module: module,
             def_index: module.def_id().unwrap().index,
+            const_integer: false,
         });
         mark
     }
@@ -156,17 +161,21 @@ impl<'a> Resolver<'a> {
 
     fn collect_def_ids(&mut self, mark: Mark, expansion: &Expansion) {
         let expansion_data = &mut self.expansion_data;
-        let module = self.current_module;
-        let def_index = expansion_data[&mark.as_u32()].def_index;
-        let visit_macro_invoc = &mut |id: ast::NodeId, def_index| {
-            expansion_data.insert(id.as_u32(), ExpansionData {
-                def_index: def_index,
+        let ExpansionData { def_index, const_integer, module } = expansion_data[&mark.as_u32()];
+        let visit_macro_invoc = &mut |invoc: map::MacroInvocationData| {
+            expansion_data.entry(invoc.id.as_u32()).or_insert(ExpansionData {
+                def_index: invoc.def_index,
+                const_integer: invoc.const_integer,
                 module: module,
             });
         };
 
         let mut def_collector = DefCollector::new(&mut self.definitions);
         def_collector.visit_macro_invoc = Some(visit_macro_invoc);
-        def_collector.with_parent(def_index, |def_collector| expansion.visit_with(def_collector));
+        def_collector.with_parent(def_index, |def_collector| if !const_integer {
+            expansion.visit_with(def_collector)
+        } else if let Expansion::Expr(ref expr) = *expansion {
+            def_collector.visit_ast_const_integer(expr);
+        });
     }
 }