Fix def id collection for const_integers in the AST.

This commit is contained in:
Jeffrey Seyfried 2016-09-23 21:13:59 +00:00
parent f34e49dd90
commit d854c362fe
3 changed files with 46 additions and 28 deletions

View File

@ -27,7 +27,13 @@ pub struct DefCollector<'a> {
hir_crate: Option<&'a hir::Crate>, hir_crate: Option<&'a hir::Crate>,
definitions: &'a mut Definitions, definitions: &'a mut Definitions,
parent_def: Option<DefIndex>, 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> { impl<'a> DefCollector<'a> {
@ -93,16 +99,15 @@ pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F)
self.parent_def = parent; self.parent_def = parent;
} }
fn visit_ast_const_integer(&mut self, expr: &Expr) { pub fn visit_ast_const_integer(&mut self, expr: &Expr) {
// Find the node which will be used after lowering. match expr.node {
if let ExprKind::Paren(ref inner) = expr.node { // Find the node which will be used after lowering.
return self.visit_ast_const_integer(inner); 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
// FIXME(eddyb) Closures should have separate // function definition IDs and expression IDs.
// function definition IDs and expression IDs. ExprKind::Closure(..) => return,
if let ExprKind::Closure(..) = expr.node { _ => {}
return;
} }
self.create_def(expr.id, DefPathData::Initializer); 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); 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 { 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(..) => ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
DefPathData::ValueNs(i.ident.name.as_str()), DefPathData::ValueNs(i.ident.name.as_str()),
ItemKind::Mac(..) if i.id == DUMMY_NODE_ID => return, // Scope placeholder 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, ItemKind::Use(..) => DefPathData::Misc,
}; };
let def = self.create_def(i.id, def_data); 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(..) => TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
DefPathData::ValueNs(ti.ident.name.as_str()), DefPathData::ValueNs(ti.ident.name.as_str()),
TraitItemKind::Type(..) => DefPathData::TypeNs(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); 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(..) => ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
DefPathData::ValueNs(ii.ident.name.as_str()), DefPathData::ValueNs(ii.ident.name.as_str()),
ImplItemKind::Type(..) => DefPathData::TypeNs(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); 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; let parent_def = self.parent_def;
match pat.node { 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, _) => { PatKind::Ident(_, id, _) => {
let def = self.create_def(pat.id, DefPathData::Binding(id.node.name.as_str())); let def = self.create_def(pat.id, DefPathData::Binding(id.node.name.as_str()));
self.parent_def = Some(def); self.parent_def = Some(def);
@ -261,7 +270,7 @@ fn visit_expr(&mut self, expr: &Expr) {
let parent_def = self.parent_def; let parent_def = self.parent_def;
match expr.node { 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::Repeat(_, ref count) => self.visit_ast_const_integer(count),
ExprKind::Closure(..) => { ExprKind::Closure(..) => {
let def = self.create_def(expr.id, DefPathData::ClosureExpr); 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) { fn visit_ty(&mut self, ty: &Ty) {
match ty.node { 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::FixedLengthVec(_, ref length) => self.visit_ast_const_integer(length),
TyKind::ImplTrait(..) => { TyKind::ImplTrait(..) => {
self.create_def(ty.id, DefPathData::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) { fn visit_stmt(&mut self, stmt: &Stmt) {
match stmt.node { 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), _ => visit::walk_stmt(self, stmt),
} }
} }

View File

@ -11,7 +11,7 @@
pub use self::Node::*; pub use self::Node::*;
use self::MapEntry::*; use self::MapEntry::*;
use self::collector::NodeCollector; 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, pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
DisambiguatedDefPathData, InlinedRootPath}; DisambiguatedDefPathData, InlinedRootPath};

View File

@ -11,7 +11,7 @@
use {Module, Resolver}; use {Module, Resolver};
use build_reduced_graph::BuildReducedGraphVisitor; use build_reduced_graph::BuildReducedGraphVisitor;
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex}; 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 std::rc::Rc;
use syntax::ast; use syntax::ast;
use syntax::errors::DiagnosticBuilder; use syntax::errors::DiagnosticBuilder;
@ -27,6 +27,9 @@
pub struct ExpansionData<'a> { pub struct ExpansionData<'a> {
pub module: Module<'a>, pub module: Module<'a>,
def_index: DefIndex, 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> { impl<'a> ExpansionData<'a> {
@ -34,6 +37,7 @@ pub fn root(graph_root: Module<'a>) -> Self {
ExpansionData { ExpansionData {
module: graph_root, module: graph_root,
def_index: CRATE_DEF_INDEX, 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 { self.expansion_data.insert(mark.as_u32(), ExpansionData {
module: module, module: module,
def_index: module.def_id().unwrap().index, def_index: module.def_id().unwrap().index,
const_integer: false,
}); });
mark 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) { fn collect_def_ids(&mut self, mark: Mark, expansion: &Expansion) {
let expansion_data = &mut self.expansion_data; let expansion_data = &mut self.expansion_data;
let module = self.current_module; let ExpansionData { def_index, const_integer, module } = expansion_data[&mark.as_u32()];
let def_index = expansion_data[&mark.as_u32()].def_index; let visit_macro_invoc = &mut |invoc: map::MacroInvocationData| {
let visit_macro_invoc = &mut |id: ast::NodeId, def_index| { expansion_data.entry(invoc.id.as_u32()).or_insert(ExpansionData {
expansion_data.insert(id.as_u32(), ExpansionData { def_index: invoc.def_index,
def_index: def_index, const_integer: invoc.const_integer,
module: module, module: module,
}); });
}; };
let mut def_collector = DefCollector::new(&mut self.definitions); let mut def_collector = DefCollector::new(&mut self.definitions);
def_collector.visit_macro_invoc = Some(visit_macro_invoc); 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);
});
} }
} }