Skip to content

Commit b889259

Browse files
committed
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.
1 parent 36fbf8c commit b889259

File tree

7 files changed

+86
-11
lines changed

7 files changed

+86
-11
lines changed

src/librustc/dep_graph/visit.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>
4545
self.visitor.visit_item(i);
4646
debug!("Ended task {:?}", task_id);
4747
}
48+
49+
fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) {
50+
// TODO -- use the def-id of the impl for now
51+
let impl_def_id = self.tcx.map.get_parent_did(i.id);
52+
let task_id = (self.dep_node_fn)(impl_def_id);
53+
let _task = self.tcx.dep_graph.in_task(task_id.clone());
54+
debug!("Started task {:?}", task_id);
55+
assert!(!self.tcx.map.is_inlined_def_id(impl_def_id));
56+
self.tcx.dep_graph.read(DepNode::Hir(impl_def_id));
57+
self.visitor.visit_impl_item(i);
58+
debug!("Ended task {:?}", task_id);
59+
}
4860
}
4961

5062
let krate = tcx.dep_graph.with_ignore(|| tcx.map.krate());

src/librustc/hir/intravisit.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,17 @@ pub trait Visitor<'v> : Sized {
9494
fn visit_nested_item(&mut self, id: ItemId) {
9595
}
9696

97-
/// Visit the top-level item and (optionally) nested items. See
97+
/// Invoked when a nested impl item is encountered. By default, does
98+
/// nothing. If you want a deep walk, you need to override to
99+
/// fetch the item contents. But most of the time, it is easier
100+
/// (and better) to invoke `Crate::visit_all_item_likes`, which visits
101+
/// all items in the crate in some order (but doesn't respect
102+
/// nesting).
103+
#[allow(unused_variables)]
104+
fn visit_nested_impl_item(&mut self, id: ImplItemId) {
105+
}
106+
107+
/// Visit the top-level item and (optionally) nested items / impl items. See
98108
/// `visit_nested_item` for details.
99109
fn visit_item(&mut self, i: &'v Item) {
100110
walk_item(self, i)
@@ -359,12 +369,14 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
359369
visitor.visit_id(item.id);
360370
visitor.visit_trait_ref(trait_ref)
361371
}
362-
ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_items) => {
372+
ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_item_ids) => {
363373
visitor.visit_id(item.id);
364374
visitor.visit_generics(type_parameters);
365375
walk_list!(visitor, visit_trait_ref, opt_trait_reference);
366376
visitor.visit_ty(typ);
367-
walk_list!(visitor, visit_impl_item, impl_items);
377+
for &impl_item_id in impl_item_ids {
378+
visitor.visit_nested_impl_item(impl_item_id);
379+
}
368380
}
369381
ItemStruct(ref struct_definition, ref generics) |
370382
ItemUnion(ref struct_definition, ref generics) => {

src/librustc/hir/itemlikevisit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::Item;
11+
use super::{Item, ImplItem};
1212
use super::intravisit::Visitor;
1313

1414
/// The "item-like visitor" visitor defines only the top-level methods

src/librustc/hir/lowering.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ impl<'a> LoweringContext<'a> {
105105
fn lower_crate(&mut self, c: &Crate) -> hir::Crate {
106106
struct ItemLowerer<'lcx, 'interner: 'lcx> {
107107
items: BTreeMap<NodeId, hir::Item>,
108+
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
108109
lctx: &'lcx mut LoweringContext<'interner>,
109110
}
110111

@@ -113,12 +114,20 @@ impl<'a> LoweringContext<'a> {
113114
self.items.insert(item.id, self.lctx.lower_item(item));
114115
visit::walk_item(self, item);
115116
}
117+
118+
fn visit_impl_item(&mut self, item: &ImplItem) {
119+
let id = self.lctx.lower_impl_item_id(item);
120+
self.impl_items.insert(id, self.lctx.lower_impl_item(item));
121+
visit::walk_impl_item(self, item);
122+
}
116123
}
117124

118-
let items = {
119-
let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: self };
125+
let (items, impl_items) = {
126+
let mut item_lowerer = ItemLowerer { items: BTreeMap::new(),
127+
impl_items: BTreeMap::new(),
128+
lctx: self };
120129
visit::walk_crate(&mut item_lowerer, c);
121-
item_lowerer.items
130+
(item_lowerer.items, item_lowerer.impl_items)
122131
};
123132

124133
hir::Crate {
@@ -127,6 +136,7 @@ impl<'a> LoweringContext<'a> {
127136
span: c.span,
128137
exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(),
129138
items: items,
139+
impl_items: impl_items,
130140
}
131141
}
132142

@@ -631,7 +641,7 @@ impl<'a> LoweringContext<'a> {
631641
}
632642
ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => {
633643
let new_impl_items = impl_items.iter()
634-
.map(|item| self.lower_impl_item(item))
644+
.map(|item| self.lower_impl_item_id(item))
635645
.collect();
636646
let ifce = ifce.as_ref().map(|trait_ref| self.lower_trait_ref(trait_ref));
637647
hir::ItemImpl(self.lower_unsafety(unsafety),
@@ -707,6 +717,10 @@ impl<'a> LoweringContext<'a> {
707717
})
708718
}
709719

720+
fn lower_impl_item_id(&mut self, i: &ImplItem) -> hir::ImplItemId {
721+
hir::ImplItemId { id: i.id }
722+
}
723+
710724
fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
711725
hir::Mod {
712726
inner: m.inner,

src/librustc/hir/map/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,15 @@ impl<'ast> Map<'ast> {
378378
self.forest.krate()
379379
}
380380

381+
pub fn impl_item(&self, id: ImplItemId) -> &'ast ImplItem {
382+
// TODO right now this triggers a read of the whole impl
383+
self.read(id.id);
384+
385+
// NB: intentionally bypass `self.forest.krate()` so that we
386+
// do not trigger a read of the whole krate here
387+
self.forest.krate.impl_item(id)
388+
}
389+
381390
/// Get the attributes on the krate. This is preferable to
382391
/// invoking `krate.attrs` because it registers a tighter
383392
/// dep-graph access.

src/librustc/hir/mod.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,13 +424,19 @@ pub struct Crate {
424424
// detected, which in turn can make compile-fail tests yield
425425
// slightly different results.
426426
pub items: BTreeMap<NodeId, Item>,
427+
428+
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
427429
}
428430

429431
impl Crate {
430432
pub fn item(&self, id: NodeId) -> &Item {
431433
&self.items[&id]
432434
}
433435

436+
pub fn impl_item(&self, id: ImplItemId) -> &ImplItem {
437+
&self.impl_items[&id]
438+
}
439+
434440
/// Visits all items in the crate in some determinstic (but
435441
/// unspecified) order. If you just need to process every item,
436442
/// but don't care about nesting, this method is the best choice.
@@ -445,6 +451,10 @@ impl Crate {
445451
for (_, item) in &self.items {
446452
visitor.visit_item(item);
447453
}
454+
455+
for (_, impl_item) in &self.impl_items {
456+
visitor.visit_impl_item(impl_item);
457+
}
448458
}
449459
}
450460

@@ -1042,6 +1052,14 @@ pub enum TraitItem_ {
10421052
TypeTraitItem(TyParamBounds, Option<P<Ty>>),
10431053
}
10441054

1055+
// The bodies for items are stored "out of line", in a separate
1056+
// hashmap in the `Crate`. Here we just record the node-id of the item
1057+
// so it can fetched later.
1058+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
1059+
pub struct ImplItemId {
1060+
pub id: NodeId,
1061+
}
1062+
10451063
/// Represents anything within an `impl` block
10461064
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
10471065
pub struct ImplItem {
@@ -1528,7 +1546,7 @@ pub enum Item_ {
15281546
Generics,
15291547
Option<TraitRef>, // (optional) trait this impl implements
15301548
P<Ty>, // self
1531-
HirVec<ImplItem>),
1549+
HirVec<ImplItemId>),
15321550
}
15331551

15341552
impl Item_ {

src/librustc/hir/print.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -808,8 +808,8 @@ impl<'a> State<'a> {
808808
space(&mut self.s)?;
809809
self.bopen()?;
810810
self.print_inner_attributes(&item.attrs)?;
811-
for impl_item in impl_items {
812-
self.print_impl_item(impl_item)?;
811+
for &impl_item in impl_items {
812+
self.print_impl_item_id(impl_item)?;
813813
}
814814
self.bclose(item.span)?;
815815
}
@@ -1020,6 +1020,16 @@ impl<'a> State<'a> {
10201020
self.ann.post(self, NodeSubItem(ti.id))
10211021
}
10221022

1023+
pub fn print_impl_item_id(&mut self, item_id: hir::ImplItemId) -> io::Result<()> {
1024+
if let Some(krate) = self.krate {
1025+
// skip nested items if krate context was not provided
1026+
let item = &krate.impl_item(item_id);
1027+
self.print_impl_item(item)
1028+
} else {
1029+
Ok(())
1030+
}
1031+
}
1032+
10231033
pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> {
10241034
self.ann.pre(self, NodeSubItem(ii.id))?;
10251035
self.hardbreak_if_not_bol()?;

0 commit comments

Comments
 (0)