Skip to content

Commit 744be0b

Browse files
committed
HIR visitor for DefCollector
So that we can work with inlined HIR from metadata.
1 parent 0c37d4b commit 744be0b

File tree

2 files changed

+175
-14
lines changed

2 files changed

+175
-14
lines changed

src/librustc/hir/map/def_collector.rs

+168-6
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,28 @@
1010

1111
use super::*;
1212

13+
use hir;
14+
use hir::intravisit;
1315
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
1416

17+
use middle::cstore::InlinedItem;
18+
1519
use syntax::ast::*;
1620
use syntax::visit;
1721

1822
/// Creates def ids for nodes in the HIR.
19-
pub struct DefCollector {
23+
pub struct DefCollector<'ast> {
24+
// If we are walking HIR (c.f., AST), we need to keep a reference to the
25+
// crate.
26+
hir_crate: Option<&'ast hir::Crate>,
2027
pub definitions: Definitions,
21-
pub parent_def: Option<DefIndex>,
28+
parent_def: Option<DefIndex>,
2229
}
2330

24-
impl DefCollector {
25-
pub fn root() -> DefCollector {
31+
impl<'ast> DefCollector<'ast> {
32+
pub fn root() -> DefCollector<'ast> {
2633
let mut collector = DefCollector {
34+
hir_crate: None,
2735
definitions: Definitions::new(),
2836
parent_def: None,
2937
};
@@ -39,8 +47,9 @@ impl DefCollector {
3947
parent_def_path: DefPath,
4048
parent_def_id: DefId,
4149
definitions: Definitions)
42-
-> DefCollector {
50+
-> DefCollector<'ast> {
4351
let mut collector = DefCollector {
52+
hir_crate: None,
4453
parent_def: None,
4554
definitions: definitions,
4655
};
@@ -57,6 +66,11 @@ impl DefCollector {
5766
collector
5867
}
5968

69+
pub fn walk_item(&mut self, ii: &'ast InlinedItem, krate: &'ast hir::Crate) {
70+
self.hir_crate = Some(krate);
71+
ii.visit(self);
72+
}
73+
6074
fn parent_def(&self) -> Option<DefIndex> {
6175
self.parent_def
6276
}
@@ -83,7 +97,7 @@ impl DefCollector {
8397
}
8498
}
8599

86-
impl<'ast> visit::Visitor<'ast> for DefCollector {
100+
impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> {
87101
fn visit_item(&mut self, i: &'ast Item) {
88102
debug!("visit_item: {:?}", i);
89103

@@ -226,3 +240,151 @@ impl<'ast> visit::Visitor<'ast> for DefCollector {
226240
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name));
227241
}
228242
}
243+
244+
// We walk the HIR rather than the AST when reading items from metadata.
245+
impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
246+
/// Because we want to track parent items and so forth, enable
247+
/// deep walking so that we walk nested items in the context of
248+
/// their outer items.
249+
fn visit_nested_item(&mut self, item_id: hir::ItemId) {
250+
debug!("visit_nested_item: {:?}", item_id);
251+
let item = self.hir_crate.unwrap().item(item_id.id);
252+
self.visit_item(item)
253+
}
254+
255+
fn visit_item(&mut self, i: &'ast hir::Item) {
256+
debug!("visit_item: {:?}", i);
257+
258+
// Pick the def data. This need not be unique, but the more
259+
// information we encapsulate into
260+
let def_data = match i.node {
261+
hir::ItemDefaultImpl(..) | hir::ItemImpl(..) =>
262+
DefPathData::Impl,
263+
hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemTrait(..) |
264+
hir::ItemExternCrate(..) | hir::ItemMod(..) | hir::ItemForeignMod(..) |
265+
hir::ItemTy(..) =>
266+
DefPathData::TypeNs(i.name),
267+
hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) =>
268+
DefPathData::ValueNs(i.name),
269+
hir::ItemUse(..) => DefPathData::Misc,
270+
};
271+
let def = self.create_def(i.id, def_data);
272+
273+
self.with_parent(def, |this| {
274+
match i.node {
275+
hir::ItemEnum(ref enum_definition, _) => {
276+
for v in &enum_definition.variants {
277+
let variant_def_index =
278+
this.create_def(v.node.data.id(),
279+
DefPathData::EnumVariant(v.node.name));
280+
281+
for field in v.node.data.fields() {
282+
this.create_def_with_parent(Some(variant_def_index),
283+
field.id,
284+
DefPathData::Field(field.name));
285+
}
286+
}
287+
}
288+
hir::ItemStruct(ref struct_def, _) => {
289+
// If this is a tuple-like struct, register the constructor.
290+
if !struct_def.is_struct() {
291+
this.create_def(struct_def.id(),
292+
DefPathData::StructCtor);
293+
}
294+
295+
for field in struct_def.fields() {
296+
this.create_def(field.id, DefPathData::Field(field.name));
297+
}
298+
}
299+
_ => {}
300+
}
301+
intravisit::walk_item(this, i);
302+
});
303+
}
304+
305+
fn visit_foreign_item(&mut self, foreign_item: &'ast hir::ForeignItem) {
306+
let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name));
307+
308+
self.with_parent(def, |this| {
309+
intravisit::walk_foreign_item(this, foreign_item);
310+
});
311+
}
312+
313+
fn visit_generics(&mut self, generics: &'ast hir::Generics) {
314+
for ty_param in generics.ty_params.iter() {
315+
self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.name));
316+
}
317+
318+
intravisit::walk_generics(self, generics);
319+
}
320+
321+
fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
322+
let def_data = match ti.node {
323+
hir::MethodTraitItem(..) | hir::ConstTraitItem(..) =>
324+
DefPathData::ValueNs(ti.name),
325+
hir::TypeTraitItem(..) => DefPathData::TypeNs(ti.name),
326+
};
327+
328+
let def = self.create_def(ti.id, def_data);
329+
self.with_parent(def, |this| {
330+
if let hir::ConstTraitItem(_, Some(ref expr)) = ti.node {
331+
this.create_def(expr.id, DefPathData::Initializer);
332+
}
333+
334+
intravisit::walk_trait_item(this, ti);
335+
});
336+
}
337+
338+
fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
339+
let def_data = match ii.node {
340+
hir::ImplItemKind::Method(..) | hir::ImplItemKind::Const(..) =>
341+
DefPathData::ValueNs(ii.name),
342+
hir::ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name),
343+
};
344+
345+
let def = self.create_def(ii.id, def_data);
346+
self.with_parent(def, |this| {
347+
if let hir::ImplItemKind::Const(_, ref expr) = ii.node {
348+
this.create_def(expr.id, DefPathData::Initializer);
349+
}
350+
351+
intravisit::walk_impl_item(this, ii);
352+
});
353+
}
354+
355+
fn visit_pat(&mut self, pat: &'ast hir::Pat) {
356+
let maybe_binding = match pat.node {
357+
hir::PatKind::Ident(_, id, _) => Some(id.node),
358+
_ => None
359+
};
360+
361+
let parent_def = self.parent_def;
362+
if let Some(id) = maybe_binding {
363+
let def = self.create_def(pat.id, DefPathData::Binding(id.name));
364+
self.parent_def = Some(def);
365+
}
366+
367+
intravisit::walk_pat(self, pat);
368+
self.parent_def = parent_def;
369+
}
370+
371+
fn visit_expr(&mut self, expr: &'ast hir::Expr) {
372+
let parent_def = self.parent_def;
373+
374+
if let hir::ExprClosure(..) = expr.node {
375+
let def = self.create_def(expr.id, DefPathData::ClosureExpr);
376+
self.parent_def = Some(def);
377+
}
378+
379+
intravisit::walk_expr(self, expr);
380+
self.parent_def = parent_def;
381+
}
382+
383+
fn visit_lifetime_def(&mut self, def: &'ast hir::LifetimeDef) {
384+
self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name));
385+
}
386+
387+
fn visit_macro_def(&mut self, macro_def: &'ast hir::MacroDef) {
388+
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name));
389+
}
390+
}

src/librustc/hir/map/mod.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -843,14 +843,13 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
843843
let ii = map.forest.inlined_items.alloc(ii);
844844
let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
845845

846-
// TODO need to save defs in metadata :-(
847-
// let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new());
848-
// let mut def_collector = DefCollector::extend(ii_parent_id,
849-
// parent_def_path.clone(),
850-
// parent_def_id,
851-
// defs);
852-
// ii.visit(&mut def_collector);
853-
// *map.definitions.borrow_mut() = def_collector.definitions;
846+
let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new());
847+
let mut def_collector = DefCollector::extend(ii_parent_id,
848+
parent_def_path.clone(),
849+
parent_def_id,
850+
defs);
851+
def_collector.walk_item(ii, map.krate());
852+
*map.definitions.borrow_mut() = def_collector.definitions;
854853

855854
let mut collector = NodeCollector::extend(map.krate(),
856855
ii,

0 commit comments

Comments
 (0)