diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2016-11-02 18:25:31 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2016-11-16 13:51:36 -0500 |
| commit | b889259e2b42479584343eb3674b7a3de1870e5b (patch) | |
| tree | f85a495d294b6030fc84257cbbfbe376638fffca | |
| parent | 36fbf8c53cd37498e5eaadf02740e2aac87f6118 (diff) | |
| download | rust-b889259e2b42479584343eb3674b7a3de1870e5b.tar.gz rust-b889259e2b42479584343eb3674b7a3de1870e5b.zip | |
separate impl-items from the impl in the HIR
This commit does not change how the incremental accounting is done, so changes (or accessses) to an impl-item are still tagged to the enclosing impl. This commits adds the "main guts" of this change. It does not build on its own.
| -rw-r--r-- | src/librustc/dep_graph/visit.rs | 12 | ||||
| -rw-r--r-- | src/librustc/hir/intravisit.rs | 18 | ||||
| -rw-r--r-- | src/librustc/hir/itemlikevisit.rs | 2 | ||||
| -rw-r--r-- | src/librustc/hir/lowering.rs | 22 | ||||
| -rw-r--r-- | src/librustc/hir/map/mod.rs | 9 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 20 | ||||
| -rw-r--r-- | src/librustc/hir/print.rs | 14 |
7 files changed, 86 insertions, 11 deletions
diff --git a/src/librustc/dep_graph/visit.rs b/src/librustc/dep_graph/visit.rs index 30de5e5288a..6d89bbba54e 100644 --- a/src/librustc/dep_graph/visit.rs +++ b/src/librustc/dep_graph/visit.rs @@ -45,6 +45,18 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx> self.visitor.visit_item(i); debug!("Ended task {:?}", task_id); } + + fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) { + // TODO -- use the def-id of the impl for now + let impl_def_id = self.tcx.map.get_parent_did(i.id); + let task_id = (self.dep_node_fn)(impl_def_id); + let _task = self.tcx.dep_graph.in_task(task_id.clone()); + debug!("Started task {:?}", task_id); + assert!(!self.tcx.map.is_inlined_def_id(impl_def_id)); + self.tcx.dep_graph.read(DepNode::Hir(impl_def_id)); + self.visitor.visit_impl_item(i); + debug!("Ended task {:?}", task_id); + } } let krate = tcx.dep_graph.with_ignore(|| tcx.map.krate()); diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 2fc27e0cea0..5a193a0ac94 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -94,7 +94,17 @@ pub trait Visitor<'v> : Sized { fn visit_nested_item(&mut self, id: ItemId) { } - /// Visit the top-level item and (optionally) nested items. See + /// Invoked when a nested impl item is encountered. By default, does + /// nothing. If you want a deep walk, you need to override to + /// fetch the item contents. But most of the time, it is easier + /// (and better) to invoke `Crate::visit_all_item_likes`, which visits + /// all items in the crate in some order (but doesn't respect + /// nesting). + #[allow(unused_variables)] + fn visit_nested_impl_item(&mut self, id: ImplItemId) { + } + + /// Visit the top-level item and (optionally) nested items / impl items. See /// `visit_nested_item` for details. fn visit_item(&mut self, i: &'v Item) { walk_item(self, i) @@ -359,12 +369,14 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_id(item.id); visitor.visit_trait_ref(trait_ref) } - ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_items) => { + ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_item_ids) => { visitor.visit_id(item.id); visitor.visit_generics(type_parameters); walk_list!(visitor, visit_trait_ref, opt_trait_reference); visitor.visit_ty(typ); - walk_list!(visitor, visit_impl_item, impl_items); + for &impl_item_id in impl_item_ids { + visitor.visit_nested_impl_item(impl_item_id); + } } ItemStruct(ref struct_definition, ref generics) | ItemUnion(ref struct_definition, ref generics) => { diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs index 6da47015d7d..22b56604428 100644 --- a/src/librustc/hir/itemlikevisit.rs +++ b/src/librustc/hir/itemlikevisit.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::Item; +use super::{Item, ImplItem}; use super::intravisit::Visitor; /// The "item-like visitor" visitor defines only the top-level methods diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index b985298e47c..0731c35ff16 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -105,6 +105,7 @@ impl<'a> LoweringContext<'a> { fn lower_crate(&mut self, c: &Crate) -> hir::Crate { struct ItemLowerer<'lcx, 'interner: 'lcx> { items: BTreeMap<NodeId, hir::Item>, + impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>, lctx: &'lcx mut LoweringContext<'interner>, } @@ -113,12 +114,20 @@ impl<'a> LoweringContext<'a> { self.items.insert(item.id, self.lctx.lower_item(item)); visit::walk_item(self, item); } + + fn visit_impl_item(&mut self, item: &ImplItem) { + let id = self.lctx.lower_impl_item_id(item); + self.impl_items.insert(id, self.lctx.lower_impl_item(item)); + visit::walk_impl_item(self, item); + } } - let items = { - let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: self }; + let (items, impl_items) = { + let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), + impl_items: BTreeMap::new(), + lctx: self }; visit::walk_crate(&mut item_lowerer, c); - item_lowerer.items + (item_lowerer.items, item_lowerer.impl_items) }; hir::Crate { @@ -127,6 +136,7 @@ impl<'a> LoweringContext<'a> { span: c.span, exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(), items: items, + impl_items: impl_items, } } @@ -631,7 +641,7 @@ impl<'a> LoweringContext<'a> { } ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => { let new_impl_items = impl_items.iter() - .map(|item| self.lower_impl_item(item)) + .map(|item| self.lower_impl_item_id(item)) .collect(); let ifce = ifce.as_ref().map(|trait_ref| self.lower_trait_ref(trait_ref)); hir::ItemImpl(self.lower_unsafety(unsafety), @@ -707,6 +717,10 @@ impl<'a> LoweringContext<'a> { }) } + fn lower_impl_item_id(&mut self, i: &ImplItem) -> hir::ImplItemId { + hir::ImplItemId { id: i.id } + } + fn lower_mod(&mut self, m: &Mod) -> hir::Mod { hir::Mod { inner: m.inner, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 39114ec4238..c629ec66ca4 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -378,6 +378,15 @@ impl<'ast> Map<'ast> { self.forest.krate() } + pub fn impl_item(&self, id: ImplItemId) -> &'ast ImplItem { + // TODO right now this triggers a read of the whole impl + self.read(id.id); + + // NB: intentionally bypass `self.forest.krate()` so that we + // do not trigger a read of the whole krate here + self.forest.krate.impl_item(id) + } + /// Get the attributes on the krate. This is preferable to /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 4716a09ad35..c9892135b1d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -424,6 +424,8 @@ pub struct Crate { // detected, which in turn can make compile-fail tests yield // slightly different results. pub items: BTreeMap<NodeId, Item>, + + pub impl_items: BTreeMap<ImplItemId, ImplItem>, } impl Crate { @@ -431,6 +433,10 @@ impl Crate { &self.items[&id] } + pub fn impl_item(&self, id: ImplItemId) -> &ImplItem { + &self.impl_items[&id] + } + /// Visits all items in the crate in some determinstic (but /// unspecified) order. If you just need to process every item, /// but don't care about nesting, this method is the best choice. @@ -445,6 +451,10 @@ impl Crate { for (_, item) in &self.items { visitor.visit_item(item); } + + for (_, impl_item) in &self.impl_items { + visitor.visit_impl_item(impl_item); + } } } @@ -1042,6 +1052,14 @@ pub enum TraitItem_ { TypeTraitItem(TyParamBounds, Option<P<Ty>>), } +// The bodies for items are stored "out of line", in a separate +// hashmap in the `Crate`. Here we just record the node-id of the item +// so it can fetched later. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ImplItemId { + pub id: NodeId, +} + /// Represents anything within an `impl` block #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct ImplItem { @@ -1528,7 +1546,7 @@ pub enum Item_ { Generics, Option<TraitRef>, // (optional) trait this impl implements P<Ty>, // self - HirVec<ImplItem>), + HirVec<ImplItemId>), } impl Item_ { diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 2c4ffb853c1..ed274b5a23e 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -808,8 +808,8 @@ impl<'a> State<'a> { space(&mut self.s)?; self.bopen()?; self.print_inner_attributes(&item.attrs)?; - for impl_item in impl_items { - self.print_impl_item(impl_item)?; + for &impl_item in impl_items { + self.print_impl_item_id(impl_item)?; } self.bclose(item.span)?; } @@ -1020,6 +1020,16 @@ impl<'a> State<'a> { self.ann.post(self, NodeSubItem(ti.id)) } + pub fn print_impl_item_id(&mut self, item_id: hir::ImplItemId) -> io::Result<()> { + if let Some(krate) = self.krate { + // skip nested items if krate context was not provided + let item = &krate.impl_item(item_id); + self.print_impl_item(item) + } else { + Ok(()) + } + } + pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> { self.ann.pre(self, NodeSubItem(ii.id))?; self.hardbreak_if_not_bol()?; |
