Skip to content

Commit 8d7c59b

Browse files
incr.comp.: Cache Hir-DepNodeIndices in the HIR map.
1 parent 942711e commit 8d7c59b

File tree

8 files changed

+345
-232
lines changed

8 files changed

+345
-232
lines changed

src/librustc/dep_graph/edges.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ impl DepGraphEdges {
244244
self.edges.insert((source, target));
245245
}
246246

247-
pub fn add_node(&mut self, node: DepNode) {
248-
self.get_or_create_node(node);
247+
pub fn add_node(&mut self, node: DepNode) -> DepNodeIndex {
248+
self.get_or_create_node(node)
249249
}
250250

251251
#[inline]

src/librustc/dep_graph/graph.rs

+8
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ impl DepGraph {
166166
self.data.as_ref().unwrap().edges.borrow_mut().add_node(node);
167167
}
168168

169+
pub fn alloc_input_node(&self, node: DepNode) -> DepNodeIndex {
170+
if let Some(ref data) = self.data {
171+
data.edges.borrow_mut().add_node(node)
172+
} else {
173+
DepNodeIndex::INVALID
174+
}
175+
}
176+
169177
/// Indicates that a previous work product exists for `v`. This is
170178
/// invoked during initial start-up based on what nodes are clean
171179
/// (and what files exist in the incr. directory).

src/librustc/hir/intravisit.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,16 @@ pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref:
835835

836836
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
837837
// NB: Deliberately force a compilation error if/when new fields are added.
838-
let ImplItem { id: _, name, ref vis, ref defaultness, ref attrs, ref node, span } = *impl_item;
838+
let ImplItem {
839+
id: _,
840+
hir_id: _,
841+
name,
842+
ref vis,
843+
ref defaultness,
844+
ref attrs,
845+
ref node,
846+
span
847+
} = *impl_item;
839848

840849
visitor.visit_name(span, name);
841850
visitor.visit_vis(vis);

src/librustc/hir/lowering.rs

+21-6
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,12 @@ impl<'a> LoweringContext<'a> {
12681268
path.span = span;
12691269

12701270
self.allocate_hir_id_counter(import.id, import);
1271-
self.with_hir_id_owner(import.id, |this| {
1271+
let LoweredNodeId {
1272+
node_id: import_node_id,
1273+
hir_id: import_hir_id,
1274+
} = self.lower_node_id(import.id);
1275+
1276+
self.with_hir_id_owner(import_node_id, |this| {
12721277
let vis = match *vis {
12731278
hir::Visibility::Public => hir::Visibility::Public,
12741279
hir::Visibility::Crate => hir::Visibility::Crate,
@@ -1282,8 +1287,9 @@ impl<'a> LoweringContext<'a> {
12821287
}
12831288
};
12841289

1285-
this.items.insert(import.id, hir::Item {
1286-
id: import.id,
1290+
this.items.insert(import_node_id, hir::Item {
1291+
id: import_node_id,
1292+
hir_id: import_hir_id,
12871293
name: import.rename.unwrap_or(ident).name,
12881294
attrs: attrs.clone(),
12891295
node: hir::ItemUse(P(path), hir::UseKind::Single),
@@ -1414,8 +1420,11 @@ impl<'a> LoweringContext<'a> {
14141420

14151421
fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
14161422
self.with_parent_def(i.id, |this| {
1423+
let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
1424+
14171425
hir::TraitItem {
1418-
id: this.lower_node_id(i.id).node_id,
1426+
id: node_id,
1427+
hir_id,
14191428
name: this.lower_ident(i.ident),
14201429
attrs: this.lower_attrs(&i.attrs),
14211430
node: match i.node {
@@ -1475,8 +1484,11 @@ impl<'a> LoweringContext<'a> {
14751484

14761485
fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
14771486
self.with_parent_def(i.id, |this| {
1487+
let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
1488+
14781489
hir::ImplItem {
1479-
id: this.lower_node_id(i.id).node_id,
1490+
id: node_id,
1491+
hir_id,
14801492
name: this.lower_ident(i.ident),
14811493
attrs: this.lower_attrs(&i.attrs),
14821494
vis: this.lower_visibility(&i.vis, None),
@@ -1567,8 +1579,11 @@ impl<'a> LoweringContext<'a> {
15671579
this.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node)
15681580
});
15691581

1582+
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
1583+
15701584
Some(hir::Item {
1571-
id: self.lower_node_id(i.id).node_id,
1585+
id: node_id,
1586+
hir_id,
15721587
name,
15731588
attrs,
15741589
node,

src/librustc/hir/map/collector.rs

+165-29
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,55 @@
1010

1111
use super::*;
1212

13+
use dep_graph::{DepGraph, DepKind, DepNodeIndex};
1314
use hir::intravisit::{Visitor, NestedVisitorMap};
1415
use std::iter::repeat;
1516
use syntax::ast::{NodeId, CRATE_NODE_ID};
1617
use syntax_pos::Span;
1718

1819
/// A Visitor that walks over the HIR and collects Nodes into a HIR map
19-
pub struct NodeCollector<'hir> {
20+
pub(super) struct NodeCollector<'a, 'hir> {
2021
/// The crate
21-
pub krate: &'hir Crate,
22+
krate: &'hir Crate,
2223
/// The node map
23-
pub(super) map: Vec<MapEntry<'hir>>,
24+
map: Vec<MapEntry<'hir>>,
2425
/// The parent of this node
25-
pub parent_node: NodeId,
26+
parent_node: NodeId,
27+
28+
current_dep_node_owner: DefIndex,
29+
current_dep_node_index: DepNodeIndex,
30+
31+
dep_graph: &'a DepGraph,
32+
definitions: &'a definitions::Definitions,
2633
}
2734

28-
impl<'hir> NodeCollector<'hir> {
29-
pub fn root(krate: &'hir Crate) -> NodeCollector<'hir> {
35+
impl<'a, 'hir> NodeCollector<'a, 'hir> {
36+
pub(super) fn root(krate: &'hir Crate,
37+
dep_graph: &'a DepGraph,
38+
definitions: &'a definitions::Definitions)
39+
-> NodeCollector<'a, 'hir> {
40+
let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX);
41+
let root_mod_dep_node = root_mod_def_path_hash.to_dep_node(DepKind::Hir);
42+
let root_mod_dep_node_index = dep_graph.alloc_input_node(root_mod_dep_node);
43+
3044
let mut collector = NodeCollector {
3145
krate,
3246
map: vec![],
3347
parent_node: CRATE_NODE_ID,
48+
current_dep_node_index: root_mod_dep_node_index,
49+
current_dep_node_owner: CRATE_DEF_INDEX,
50+
dep_graph,
51+
definitions,
3452
};
35-
collector.insert_entry(CRATE_NODE_ID, RootCrate);
53+
collector.insert_entry(CRATE_NODE_ID, RootCrate(root_mod_dep_node_index));
3654

3755
collector
3856
}
3957

58+
pub(super) fn into_map(self) -> Vec<MapEntry<'hir>> {
59+
self.map
60+
}
61+
4062
fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'hir>) {
4163
debug!("hir_map: {:?} => {:?}", id, entry);
4264
let len = self.map.len();
@@ -47,8 +69,55 @@ impl<'hir> NodeCollector<'hir> {
4769
}
4870

4971
fn insert(&mut self, id: NodeId, node: Node<'hir>) {
50-
let entry = MapEntry::from_node(self.parent_node, node);
72+
let parent = self.parent_node;
73+
let dep_node_index = self.current_dep_node_index;
74+
75+
let entry = match node {
76+
NodeItem(n) => EntryItem(parent, dep_node_index, n),
77+
NodeForeignItem(n) => EntryForeignItem(parent, dep_node_index, n),
78+
NodeTraitItem(n) => EntryTraitItem(parent, dep_node_index, n),
79+
NodeImplItem(n) => EntryImplItem(parent, dep_node_index, n),
80+
NodeVariant(n) => EntryVariant(parent, dep_node_index, n),
81+
NodeField(n) => EntryField(parent, dep_node_index, n),
82+
NodeExpr(n) => EntryExpr(parent, dep_node_index, n),
83+
NodeStmt(n) => EntryStmt(parent, dep_node_index, n),
84+
NodeTy(n) => EntryTy(parent, dep_node_index, n),
85+
NodeTraitRef(n) => EntryTraitRef(parent, dep_node_index, n),
86+
NodeBinding(n) => EntryBinding(parent, dep_node_index, n),
87+
NodePat(n) => EntryPat(parent, dep_node_index, n),
88+
NodeBlock(n) => EntryBlock(parent, dep_node_index, n),
89+
NodeStructCtor(n) => EntryStructCtor(parent, dep_node_index, n),
90+
NodeLifetime(n) => EntryLifetime(parent, dep_node_index, n),
91+
NodeTyParam(n) => EntryTyParam(parent, dep_node_index, n),
92+
NodeVisibility(n) => EntryVisibility(parent, dep_node_index, n),
93+
NodeLocal(n) => EntryLocal(parent, dep_node_index, n),
94+
};
95+
96+
// Make sure that the DepNode of some node coincides with the HirId
97+
// owner of that node.
98+
if cfg!(debug_assertions) {
99+
let hir_id_owner = self.definitions.node_to_hir_id(id).owner;
100+
101+
if hir_id_owner != self.current_dep_node_owner {
102+
let node_str = match self.definitions.opt_def_index(id) {
103+
Some(def_index) => {
104+
self.definitions.def_path(def_index).to_string_no_crate()
105+
}
106+
None => format!("{:?}", node)
107+
};
108+
109+
bug!("inconsistent DepNode for `{}`: \
110+
current_dep_node_owner={}, hir_id.owner={}",
111+
node_str,
112+
self.definitions
113+
.def_path(self.current_dep_node_owner)
114+
.to_string_no_crate(),
115+
self.definitions.def_path(hir_id_owner).to_string_no_crate())
116+
}
117+
}
118+
51119
self.insert_entry(id, entry);
120+
52121
}
53122

54123
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_id: NodeId, f: F) {
@@ -57,9 +126,27 @@ impl<'hir> NodeCollector<'hir> {
57126
f(self);
58127
self.parent_node = parent_node;
59128
}
129+
130+
fn with_dep_node_owner<F: FnOnce(&mut Self)>(&mut self,
131+
dep_node_owner: DefIndex,
132+
f: F) {
133+
let prev_owner = self.current_dep_node_owner;
134+
let prev_index = self.current_dep_node_index;
135+
136+
// When we enter a new owner (item, impl item, or trait item), we always
137+
// start out again with DepKind::Hir.
138+
let new_dep_node = self.definitions
139+
.def_path_hash(dep_node_owner)
140+
.to_dep_node(DepKind::Hir);
141+
self.current_dep_node_index = self.dep_graph.alloc_input_node(new_dep_node);
142+
self.current_dep_node_owner = dep_node_owner;
143+
f(self);
144+
self.current_dep_node_index = prev_index;
145+
self.current_dep_node_owner = prev_owner;
146+
}
60147
}
61148

62-
impl<'hir> Visitor<'hir> for NodeCollector<'hir> {
149+
impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
63150
/// Because we want to track parent items and so forth, enable
64151
/// deep walking so that we walk nested items in the context of
65152
/// their outer items.
@@ -82,25 +169,37 @@ impl<'hir> Visitor<'hir> for NodeCollector<'hir> {
82169
}
83170

84171
fn visit_nested_body(&mut self, id: BodyId) {
172+
// When we enter a body, we switch to DepKind::HirBody.
173+
// Note that current_dep_node_index might already be DepKind::HirBody,
174+
// e.g. when entering the body of a closure that is already part of a
175+
// surrounding body. That's expected and not a problem.
176+
let prev_index = self.current_dep_node_index;
177+
let new_dep_node = self.definitions
178+
.def_path_hash(self.current_dep_node_owner)
179+
.to_dep_node(DepKind::HirBody);
180+
self.current_dep_node_index = self.dep_graph.alloc_input_node(new_dep_node);
85181
self.visit_body(self.krate.body(id));
182+
self.current_dep_node_index = prev_index;
86183
}
87184

88185
fn visit_item(&mut self, i: &'hir Item) {
89186
debug!("visit_item: {:?}", i);
90-
91-
self.insert(i.id, NodeItem(i));
92-
93-
self.with_parent(i.id, |this| {
94-
match i.node {
95-
ItemStruct(ref struct_def, _) => {
96-
// If this is a tuple-like struct, register the constructor.
97-
if !struct_def.is_struct() {
98-
this.insert(struct_def.id(), NodeStructCtor(struct_def));
187+
debug_assert_eq!(i.hir_id.owner,
188+
self.definitions.opt_def_index(i.id).unwrap());
189+
self.with_dep_node_owner(i.hir_id.owner, |this| {
190+
this.insert(i.id, NodeItem(i));
191+
this.with_parent(i.id, |this| {
192+
match i.node {
193+
ItemStruct(ref struct_def, _) => {
194+
// If this is a tuple-like struct, register the constructor.
195+
if !struct_def.is_struct() {
196+
this.insert(struct_def.id(), NodeStructCtor(struct_def));
197+
}
99198
}
199+
_ => {}
100200
}
101-
_ => {}
102-
}
103-
intravisit::walk_item(this, i);
201+
intravisit::walk_item(this, i);
202+
});
104203
});
105204
}
106205

@@ -121,18 +220,26 @@ impl<'hir> Visitor<'hir> for NodeCollector<'hir> {
121220
}
122221

123222
fn visit_trait_item(&mut self, ti: &'hir TraitItem) {
124-
self.insert(ti.id, NodeTraitItem(ti));
125-
126-
self.with_parent(ti.id, |this| {
127-
intravisit::walk_trait_item(this, ti);
223+
debug_assert_eq!(ti.hir_id.owner,
224+
self.definitions.opt_def_index(ti.id).unwrap());
225+
self.with_dep_node_owner(ti.hir_id.owner, |this| {
226+
this.insert(ti.id, NodeTraitItem(ti));
227+
228+
this.with_parent(ti.id, |this| {
229+
intravisit::walk_trait_item(this, ti);
230+
});
128231
});
129232
}
130233

131234
fn visit_impl_item(&mut self, ii: &'hir ImplItem) {
132-
self.insert(ii.id, NodeImplItem(ii));
133-
134-
self.with_parent(ii.id, |this| {
135-
intravisit::walk_impl_item(this, ii);
235+
debug_assert_eq!(ii.hir_id.owner,
236+
self.definitions.opt_def_index(ii.id).unwrap());
237+
self.with_dep_node_owner(ii.hir_id.owner, |this| {
238+
this.insert(ii.id, NodeImplItem(ii));
239+
240+
this.with_parent(ii.id, |this| {
241+
intravisit::walk_impl_item(this, ii);
242+
});
136243
});
137244
}
138245

@@ -238,4 +345,33 @@ impl<'hir> Visitor<'hir> for NodeCollector<'hir> {
238345
intravisit::walk_struct_field(this, field);
239346
});
240347
}
348+
349+
fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) {
350+
// Do not visit the duplicate information in TraitItemRef. We want to
351+
// map the actual nodes, not the duplicate ones in the *Ref.
352+
let TraitItemRef {
353+
id,
354+
name: _,
355+
kind: _,
356+
span: _,
357+
defaultness: _,
358+
} = *ii;
359+
360+
self.visit_nested_trait_item(id);
361+
}
362+
363+
fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) {
364+
// Do not visit the duplicate information in ImplItemRef. We want to
365+
// map the actual nodes, not the duplicate ones in the *Ref.
366+
let ImplItemRef {
367+
id,
368+
name: _,
369+
kind: _,
370+
span: _,
371+
vis: _,
372+
defaultness: _,
373+
} = *ii;
374+
375+
self.visit_nested_impl_item(id);
376+
}
241377
}

0 commit comments

Comments
 (0)