Skip to content

Commit aea57ae

Browse files
committed
Don't hash HIR with bodies thrice
1 parent 0e316e2 commit aea57ae

File tree

2 files changed

+43
-37
lines changed

2 files changed

+43
-37
lines changed

src/librustc/hir/map/collector.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,10 @@ fn hash_body(
6363
def_path_hash: DefPathHash,
6464
item_like: impl for<'a> HashStable<StableHashingContext<'a>>,
6565
hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>,
66-
) {
66+
) -> Fingerprint {
6767
let hash = hash(hcx, HirItemLike { item_like: &item_like });
6868
hir_body_nodes.push((def_path_hash, hash));
69+
hash
6970
}
7071

7172
fn upstream_crates(cstore: &dyn CrateStore) -> Vec<(Symbol, Fingerprint, Svh)> {
@@ -96,7 +97,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
9697

9798
let mut hir_body_nodes = Vec::new();
9899

99-
{
100+
let hash = {
100101
let Crate {
101102
ref item,
102103
// These fields are handled separately:
@@ -137,6 +138,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
137138
collector.insert_entry(
138139
hir::CRATE_HIR_ID,
139140
Entry { parent: hir::CRATE_HIR_ID, node: Node::Crate(&krate.item) },
141+
hash,
140142
);
141143

142144
collector
@@ -197,27 +199,24 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
197199
(self.owner_map, self.owner_items_map, svh)
198200
}
199201

200-
fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>) {
202+
fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>, hash: Fingerprint) {
201203
let i = id.local_id.as_u32() as usize;
202204

203205
let owner = HirOwner { parent: entry.parent, node: entry.node };
204206

205207
let arena = self.arena;
206-
let krate = self.krate;
207208

208209
let items = self.owner_items_map.entry(id.owner).or_insert_with(|| {
209210
arena.alloc(HirOwnerItems {
210-
// Insert a dummy node which will be overwritten
211-
// when we call `insert_entry` on the HIR owner.
212-
owner: Node::Crate(&krate.item),
211+
hash,
213212
items: IndexVec::new(),
214213
bodies: FxHashMap::default(),
215214
})
216215
});
217216

218217
if i == 0 {
219-
// Overwrite the dummy node with the real HIR owner.
220-
items.owner = entry.node;
218+
// Overwrite the dummy hash with the real HIR owner hash.
219+
items.hash = hash;
221220

222221
self.owner_map.insert(id.owner, self.arena.alloc(owner));
223222
// FIXME: feature(impl_trait_in_bindings) broken and trigger this assert
@@ -234,6 +233,10 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
234233
}
235234

236235
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
236+
self.insert_with_hash(span, hir_id, node, Fingerprint::ZERO)
237+
}
238+
239+
fn insert_with_hash(&mut self, span: Span, hir_id: HirId, node: Node<'hir>, hash: Fingerprint) {
237240
let entry = Entry { parent: self.parent_node, node };
238241

239242
// Make sure that the DepNode of some node coincides with the HirId
@@ -269,7 +272,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
269272
}
270273
}
271274

272-
self.insert_entry(hir_id, entry);
275+
self.insert_entry(hir_id, entry, hash);
273276
}
274277

275278
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
@@ -281,7 +284,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
281284

282285
fn with_dep_node_owner<
283286
T: for<'b> HashStable<StableHashingContext<'b>>,
284-
F: FnOnce(&mut Self),
287+
F: FnOnce(&mut Self, Fingerprint),
285288
>(
286289
&mut self,
287290
dep_node_owner: DefIndex,
@@ -292,10 +295,10 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
292295

293296
let def_path_hash = self.definitions.def_path_hash(dep_node_owner);
294297

295-
hash_body(&mut self.hcx, def_path_hash, item_like, &mut self.hir_body_nodes);
298+
let hash = hash_body(&mut self.hcx, def_path_hash, item_like, &mut self.hir_body_nodes);
296299

297300
self.current_dep_node_owner = dep_node_owner;
298-
f(self);
301+
f(self, hash);
299302
self.current_dep_node_owner = prev_owner;
300303
}
301304
}
@@ -342,8 +345,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
342345
i.hir_id.owner,
343346
self.definitions.opt_def_index(self.hir_to_node_id[&i.hir_id]).unwrap()
344347
);
345-
self.with_dep_node_owner(i.hir_id.owner, i, |this| {
346-
this.insert(i.span, i.hir_id, Node::Item(i));
348+
self.with_dep_node_owner(i.hir_id.owner, i, |this, hash| {
349+
this.insert_with_hash(i.span, i.hir_id, Node::Item(i), hash);
347350
this.with_parent(i.hir_id, |this| {
348351
if let ItemKind::Struct(ref struct_def, _) = i.kind {
349352
// If this is a tuple or unit-like struct, register the constructor.
@@ -374,8 +377,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
374377
ti.hir_id.owner,
375378
self.definitions.opt_def_index(self.hir_to_node_id[&ti.hir_id]).unwrap()
376379
);
377-
self.with_dep_node_owner(ti.hir_id.owner, ti, |this| {
378-
this.insert(ti.span, ti.hir_id, Node::TraitItem(ti));
380+
self.with_dep_node_owner(ti.hir_id.owner, ti, |this, hash| {
381+
this.insert_with_hash(ti.span, ti.hir_id, Node::TraitItem(ti), hash);
379382

380383
this.with_parent(ti.hir_id, |this| {
381384
intravisit::walk_trait_item(this, ti);
@@ -388,8 +391,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
388391
ii.hir_id.owner,
389392
self.definitions.opt_def_index(self.hir_to_node_id[&ii.hir_id]).unwrap()
390393
);
391-
self.with_dep_node_owner(ii.hir_id.owner, ii, |this| {
392-
this.insert(ii.span, ii.hir_id, Node::ImplItem(ii));
394+
self.with_dep_node_owner(ii.hir_id.owner, ii, |this, hash| {
395+
this.insert_with_hash(ii.span, ii.hir_id, Node::ImplItem(ii), hash);
393396

394397
this.with_parent(ii.hir_id, |this| {
395398
intravisit::walk_impl_item(this, ii);
@@ -508,8 +511,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
508511
let node_id = self.hir_to_node_id[&macro_def.hir_id];
509512
let def_index = self.definitions.opt_def_index(node_id).unwrap();
510513

511-
self.with_dep_node_owner(def_index, macro_def, |this| {
512-
this.insert(macro_def.span, macro_def.hir_id, Node::MacroDef(macro_def));
514+
self.with_dep_node_owner(def_index, macro_def, |this, hash| {
515+
this.insert_with_hash(
516+
macro_def.span,
517+
macro_def.hir_id,
518+
Node::MacroDef(macro_def),
519+
hash,
520+
);
513521
});
514522
}
515523

src/librustc/hir/mod.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod map;
88
use crate::ich::StableHashingContext;
99
use crate::ty::query::Providers;
1010
use crate::ty::TyCtxt;
11+
use rustc_data_structures::fingerprint::Fingerprint;
1112
use rustc_data_structures::fx::FxHashMap;
1213
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
1314
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@@ -17,42 +18,39 @@ use rustc_hir::ItemLocalId;
1718
use rustc_hir::Node;
1819
use rustc_index::vec::IndexVec;
1920

20-
#[derive(HashStable)]
2121
pub struct HirOwner<'tcx> {
2222
parent: HirId,
2323
node: Node<'tcx>,
2424
}
2525

26-
#[derive(Clone)]
27-
pub struct HirItem<'tcx> {
28-
parent: ItemLocalId,
29-
node: Node<'tcx>,
30-
}
31-
32-
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for HirItem<'tcx> {
26+
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for HirOwner<'tcx> {
3327
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
34-
let HirItem { parent, node } = self;
28+
let HirOwner { parent, node } = self;
3529
hcx.while_hashing_hir_bodies(false, |hcx| {
3630
parent.hash_stable(hcx, hasher);
3731
node.hash_stable(hcx, hasher);
3832
});
3933
}
4034
}
4135

36+
#[derive(Clone)]
37+
pub struct HirItem<'tcx> {
38+
parent: ItemLocalId,
39+
node: Node<'tcx>,
40+
}
41+
4242
pub struct HirOwnerItems<'tcx> {
43-
owner: Node<'tcx>,
43+
hash: Fingerprint,
4444
items: IndexVec<ItemLocalId, Option<HirItem<'tcx>>>,
4545
bodies: FxHashMap<ItemLocalId, &'tcx Body<'tcx>>,
4646
}
4747

4848
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for HirOwnerItems<'tcx> {
4949
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
50-
// We ignore the `items` and `bodies` fields since these refer to information reachable
51-
// when hashing `owner` with its bodies.
52-
let HirOwnerItems { owner, items: _, bodies: _ } = *self;
53-
hcx.while_hashing_hir_bodies(true, |hcx| {
54-
owner.hash_stable(hcx, hasher);
55-
});
50+
// We ignore the `items` and `bodies` fields since these refer to information included in
51+
// `hash` which is hashed in the collector and used for the crate hash.
52+
let HirOwnerItems { hash, items: _, bodies: _ } = *self;
53+
hash.hash_stable(hcx, hasher);
5654
}
5755
}
5856

0 commit comments

Comments
 (0)