From d854c362feb29125deebac562ec49da0eb3866bc Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Fri, 23 Sep 2016 21:13:59 +0000 Subject: [PATCH] Fix def id collection for `const_integer`s in the AST. --- src/librustc/hir/map/def_collector.rs | 49 ++++++++++++++++----------- src/librustc/hir/map/mod.rs | 2 +- src/librustc_resolve/macros.rs | 23 +++++++++---- 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, - 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 @@ pub fn with_parent(&mut self, parent_def: DefIndex, f: F) 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 @@ fn visit_hir_const_integer(&mut self, expr: &hir::Expr) { 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 @@ fn visit_item(&mut self, i: &Item) { 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 @@ fn visit_trait_item(&mut self, ti: &TraitItem) { 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 @@ fn visit_impl_item(&mut self, ii: &ImplItem) { 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 @@ fn visit_pat(&mut self, pat: &Pat) { 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 @@ fn visit_expr(&mut self, expr: &Expr) { 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 @@ fn visit_expr(&mut self, expr: &Expr) { 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 @@ fn visit_macro_def(&mut self, macro_def: &MacroDef) { 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 @@ 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 @@ pub fn root(graph_root: Module<'a>) -> Self { ExpansionData { module: graph_root, def_index: CRATE_DEF_INDEX, + const_integer: false, } } } @@ -49,6 +53,7 @@ fn get_module_scope(&mut self, id: ast::NodeId) -> Mark { 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 @@ fn suggest_macro_name(&mut self, name: &str, err: &mut DiagnosticBuilder<'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); + }); } }