Skip to content

Commit 6e2a344

Browse files
committed
Auto merge of #83114 - cjgillot:hop, r=eddyb
Move HIR parenting information out of hir_owner Split out of #82681. The parent of a HIR node and its content are currently bundled together, but are rarely used together. This PR separates both information in two distinct queries for HIR owners. This reduces incremental invalidation for HIR items that appear within a function body when this body (and the local ids) changes.
2 parents 5f304a5 + d794cb0 commit 6e2a344

File tree

12 files changed

+289
-273
lines changed

12 files changed

+289
-273
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
338338
let mut generic_args = vec![];
339339
for (idx, arg) in args.into_iter().enumerate() {
340340
if legacy_args_idx.contains(&idx) {
341-
let parent_def_id = self.current_hir_id_owner.last().unwrap().0;
341+
let parent_def_id = self.current_hir_id_owner.0;
342342
let node_id = self.resolver.next_node_id();
343343

344344
// Add a definition for the in-band const def.

compiler/rustc_ast_lowering/src/lib.rs

+10-16
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ struct LoweringContext<'a, 'hir: 'a> {
165165

166166
type_def_lifetime_params: DefIdMap<usize>,
167167

168-
current_hir_id_owner: Vec<(LocalDefId, u32)>,
168+
current_hir_id_owner: (LocalDefId, u32),
169169
item_local_id_counters: NodeMap<u32>,
170170
node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
171171

@@ -321,7 +321,7 @@ pub fn lower_crate<'a, 'hir>(
321321
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
322322
type_def_lifetime_params: Default::default(),
323323
current_module: CRATE_DEF_ID,
324-
current_hir_id_owner: vec![(CRATE_DEF_ID, 0)],
324+
current_hir_id_owner: (CRATE_DEF_ID, 0),
325325
item_local_id_counters: Default::default(),
326326
node_id_to_hir_id: IndexVec::new(),
327327
generator_kind: None,
@@ -594,9 +594,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
594594
.insert(owner, HIR_ID_COUNTER_LOCKED)
595595
.unwrap_or_else(|| panic!("no `item_local_id_counters` entry for {:?}", owner));
596596
let def_id = self.resolver.local_def_id(owner);
597-
self.current_hir_id_owner.push((def_id, counter));
597+
let old_owner = std::mem::replace(&mut self.current_hir_id_owner, (def_id, counter));
598598
let ret = f(self);
599-
let (new_def_id, new_counter) = self.current_hir_id_owner.pop().unwrap();
599+
let (new_def_id, new_counter) =
600+
std::mem::replace(&mut self.current_hir_id_owner, old_owner);
600601

601602
debug_assert!(def_id == new_def_id);
602603
debug_assert!(new_counter >= counter);
@@ -614,8 +615,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
614615
/// properly. Calling the method twice with the same `NodeId` is fine though.
615616
fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
616617
self.lower_node_id_generic(ast_node_id, |this| {
617-
let &mut (owner, ref mut local_id_counter) =
618-
this.current_hir_id_owner.last_mut().unwrap();
618+
let &mut (owner, ref mut local_id_counter) = &mut this.current_hir_id_owner;
619619
let local_id = *local_id_counter;
620620
*local_id_counter += 1;
621621
hir::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) }
@@ -868,10 +868,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
868868
// wouldn't have been added yet.
869869
let generics = this.lower_generics_mut(
870870
generics,
871-
ImplTraitContext::Universal(
872-
&mut params,
873-
this.current_hir_id_owner.last().unwrap().0,
874-
),
871+
ImplTraitContext::Universal(&mut params, this.current_hir_id_owner.0),
875872
);
876873
let res = f(this, &mut params);
877874
(params, (generics, res))
@@ -1077,7 +1074,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10771074
}
10781075
AssocTyConstraintKind::Bound { ref bounds } => {
10791076
let mut capturable_lifetimes;
1080-
let mut parent_def_id = self.current_hir_id_owner.last().unwrap().0;
1077+
let mut parent_def_id = self.current_hir_id_owner.0;
10811078
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
10821079
let (desugar_to_impl_trait, itctx) = match itctx {
10831080
// We are in the return position:
@@ -1198,7 +1195,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11981195

11991196
// Construct a AnonConst where the expr is the "ty"'s path.
12001197

1201-
let parent_def_id = self.current_hir_id_owner.last().unwrap().0;
1198+
let parent_def_id = self.current_hir_id_owner.0;
12021199
let node_id = self.resolver.next_node_id();
12031200

12041201
// Add a definition for the in-band const def.
@@ -1814,10 +1811,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18141811
if let Some((_, ibty)) = &mut in_band_ty_params {
18151812
this.lower_ty_direct(
18161813
&param.ty,
1817-
ImplTraitContext::Universal(
1818-
ibty,
1819-
this.current_hir_id_owner.last().unwrap().0,
1820-
),
1814+
ImplTraitContext::Universal(ibty, this.current_hir_id_owner.0),
18211815
)
18221816
} else {
18231817
this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())

compiler/rustc_middle/src/arena.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ macro_rules! arena_types {
9191
[] predicates: rustc_middle::ty::PredicateInner<$tcx>,
9292

9393
// HIR query types
94-
[few] indexed_hir: rustc_middle::hir::map::IndexedHir<$tcx>,
94+
[few] indexed_hir: rustc_middle::hir::IndexedHir<$tcx>,
9595
[few] hir_definitions: rustc_hir::definitions::Definitions,
9696
[] hir_owner: rustc_middle::hir::Owner<$tcx>,
9797
[] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$tcx>,

compiler/rustc_middle/src/hir/map/collector.rs

+46-93
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
use crate::arena::Arena;
2-
use crate::hir::map::{Entry, HirOwnerData, Map};
3-
use crate::hir::{Owner, OwnerNodes, ParentedNode};
2+
use crate::hir::map::{HirOwnerData, Map};
3+
use crate::hir::{IndexedHir, Owner, OwnerNodes, ParentedNode};
44
use crate::ich::StableHashingContext;
5-
use crate::middle::cstore::CrateStore;
65
use rustc_data_structures::fingerprint::Fingerprint;
76
use rustc_data_structures::fx::FxHashMap;
87
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
9-
use rustc_data_structures::svh::Svh;
108
use rustc_hir as hir;
9+
use rustc_hir::def_id::LocalDefId;
1110
use rustc_hir::def_id::CRATE_DEF_INDEX;
12-
use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE};
13-
use rustc_hir::definitions::{self, DefPathHash};
11+
use rustc_hir::definitions;
1412
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
1513
use rustc_hir::*;
1614
use rustc_index::vec::{Idx, IndexVec};
17-
use rustc_session::{CrateDisambiguator, Session};
15+
use rustc_session::Session;
1816
use rustc_span::source_map::SourceMap;
19-
use rustc_span::{Span, Symbol, DUMMY_SP};
17+
use rustc_span::{Span, DUMMY_SP};
2018

2119
use std::iter::repeat;
2220

@@ -31,6 +29,7 @@ pub(super) struct NodeCollector<'a, 'hir> {
3129
source_map: &'a SourceMap,
3230

3331
map: IndexVec<LocalDefId, HirOwnerData<'hir>>,
32+
parenting: FxHashMap<LocalDefId, HirId>,
3433

3534
/// The parent of this node
3635
parent_node: hir::HirId,
@@ -40,10 +39,6 @@ pub(super) struct NodeCollector<'a, 'hir> {
4039
definitions: &'a definitions::Definitions,
4140

4241
hcx: StableHashingContext<'a>,
43-
44-
// We are collecting HIR hashes here so we can compute the
45-
// crate hash from them later on.
46-
hir_body_nodes: Vec<(DefPathHash, Fingerprint)>,
4742
}
4843

4944
fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V) {
@@ -58,34 +53,20 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
5853

5954
fn hash_body(
6055
hcx: &mut StableHashingContext<'_>,
61-
def_path_hash: DefPathHash,
6256
item_like: impl for<'a> HashStable<StableHashingContext<'a>>,
63-
hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>,
6457
) -> Fingerprint {
65-
let hash = {
66-
let mut stable_hasher = StableHasher::new();
67-
hcx.while_hashing_hir_bodies(true, |hcx| {
68-
item_like.hash_stable(hcx, &mut stable_hasher);
69-
});
70-
stable_hasher.finish()
71-
};
72-
hir_body_nodes.push((def_path_hash, hash));
73-
hash
58+
let mut stable_hasher = StableHasher::new();
59+
hcx.while_hashing_hir_bodies(true, |hcx| {
60+
item_like.hash_stable(hcx, &mut stable_hasher);
61+
});
62+
stable_hasher.finish()
7463
}
7564

76-
fn upstream_crates(cstore: &dyn CrateStore) -> Vec<(Symbol, Fingerprint, Svh)> {
77-
let mut upstream_crates: Vec<_> = cstore
78-
.crates_untracked()
79-
.iter()
80-
.map(|&cnum| {
81-
let name = cstore.crate_name_untracked(cnum);
82-
let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
83-
let hash = cstore.crate_hash_untracked(cnum);
84-
(name, disambiguator, hash)
85-
})
86-
.collect();
87-
upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name.as_str(), dis));
88-
upstream_crates
65+
/// Represents an entry and its parent `HirId`.
66+
#[derive(Copy, Clone, Debug)]
67+
pub struct Entry<'hir> {
68+
parent: HirId,
69+
node: Node<'hir>,
8970
}
9071

9172
impl<'a, 'hir> NodeCollector<'a, 'hir> {
@@ -96,11 +77,6 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
9677
definitions: &'a definitions::Definitions,
9778
mut hcx: StableHashingContext<'a>,
9879
) -> NodeCollector<'a, 'hir> {
99-
let root_mod_def_path_hash =
100-
definitions.def_path_hash(LocalDefId { local_def_index: CRATE_DEF_INDEX });
101-
102-
let mut hir_body_nodes = Vec::new();
103-
10480
let hash = {
10581
let Crate {
10682
ref item,
@@ -120,7 +96,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
12096
attrs: _,
12197
} = *krate;
12298

123-
hash_body(&mut hcx, root_mod_def_path_hash, item, &mut hir_body_nodes)
99+
hash_body(&mut hcx, item)
124100
};
125101

126102
let mut collector = NodeCollector {
@@ -131,10 +107,10 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
131107
current_dep_node_owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
132108
definitions,
133109
hcx,
134-
hir_body_nodes,
135110
map: (0..definitions.def_index_count())
136111
.map(|_| HirOwnerData { signature: None, with_bodies: None })
137112
.collect(),
113+
parenting: FxHashMap::default(),
138114
};
139115
collector.insert_entry(
140116
hir::CRATE_HIR_ID,
@@ -145,55 +121,13 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
145121
collector
146122
}
147123

148-
pub(super) fn finalize_and_compute_crate_hash(
149-
mut self,
150-
crate_disambiguator: CrateDisambiguator,
151-
cstore: &dyn CrateStore,
152-
commandline_args_hash: u64,
153-
) -> (IndexVec<LocalDefId, HirOwnerData<'hir>>, Svh) {
124+
pub(super) fn finalize_and_compute_crate_hash(mut self) -> IndexedHir<'hir> {
154125
// Insert bodies into the map
155126
for (id, body) in self.krate.bodies.iter() {
156127
let bodies = &mut self.map[id.hir_id.owner].with_bodies.as_mut().unwrap().bodies;
157128
assert!(bodies.insert(id.hir_id.local_id, body).is_none());
158129
}
159-
160-
self.hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
161-
162-
let node_hashes = self.hir_body_nodes.iter().fold(
163-
Fingerprint::ZERO,
164-
|combined_fingerprint, &(def_path_hash, fingerprint)| {
165-
combined_fingerprint.combine(def_path_hash.0.combine(fingerprint))
166-
},
167-
);
168-
169-
let upstream_crates = upstream_crates(cstore);
170-
171-
// We hash the final, remapped names of all local source files so we
172-
// don't have to include the path prefix remapping commandline args.
173-
// If we included the full mapping in the SVH, we could only have
174-
// reproducible builds by compiling from the same directory. So we just
175-
// hash the result of the mapping instead of the mapping itself.
176-
let mut source_file_names: Vec<_> = self
177-
.source_map
178-
.files()
179-
.iter()
180-
.filter(|source_file| source_file.cnum == LOCAL_CRATE)
181-
.map(|source_file| source_file.name_hash)
182-
.collect();
183-
184-
source_file_names.sort_unstable();
185-
186-
let crate_hash_input = (
187-
((node_hashes, upstream_crates), source_file_names),
188-
(commandline_args_hash, crate_disambiguator.to_fingerprint()),
189-
);
190-
191-
let mut stable_hasher = StableHasher::new();
192-
crate_hash_input.hash_stable(&mut self.hcx, &mut stable_hasher);
193-
let crate_hash: Fingerprint = stable_hasher.finish();
194-
195-
let svh = Svh::new(crate_hash.to_smaller_hash());
196-
(self.map, svh)
130+
IndexedHir { map: self.map, parenting: self.parenting }
197131
}
198132

199133
fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>, hash: Fingerprint) {
@@ -218,8 +152,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
218152
nodes.hash = hash;
219153

220154
debug_assert!(data.signature.is_none());
221-
data.signature =
222-
Some(self.arena.alloc(Owner { parent: entry.parent, node: entry.node }));
155+
data.signature = Some(self.arena.alloc(Owner { node: entry.node }));
223156

224157
let dk_parent = self.definitions.def_key(id.owner).parent;
225158
if let Some(dk_parent) = dk_parent {
@@ -231,6 +164,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
231164
id.owner, dk_parent, entry.parent,
232165
)
233166
}
167+
168+
debug_assert_eq!(self.parenting.get(&id.owner), Some(&entry.parent));
234169
}
235170
} else {
236171
assert_eq!(entry.parent.owner, id.owner);
@@ -294,15 +229,28 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
294229
f: F,
295230
) {
296231
let prev_owner = self.current_dep_node_owner;
297-
298-
let def_path_hash = self.definitions.def_path_hash(dep_node_owner);
299-
300-
let hash = hash_body(&mut self.hcx, def_path_hash, item_like, &mut self.hir_body_nodes);
232+
let hash = hash_body(&mut self.hcx, item_like);
301233

302234
self.current_dep_node_owner = dep_node_owner;
303235
f(self, hash);
304236
self.current_dep_node_owner = prev_owner;
305237
}
238+
239+
fn insert_nested(&mut self, item: LocalDefId) {
240+
#[cfg(debug_assertions)]
241+
{
242+
let dk_parent = self.definitions.def_key(item).parent.unwrap();
243+
let dk_parent = LocalDefId { local_def_index: dk_parent };
244+
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
245+
debug_assert_eq!(
246+
dk_parent.owner, self.parent_node.owner,
247+
"Different parents for {:?}",
248+
item
249+
)
250+
}
251+
252+
assert_eq!(self.parenting.insert(item, self.parent_node), None);
253+
}
306254
}
307255

308256
impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
@@ -318,18 +266,22 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
318266

319267
fn visit_nested_item(&mut self, item: ItemId) {
320268
debug!("visit_nested_item: {:?}", item);
269+
self.insert_nested(item.def_id);
321270
self.visit_item(self.krate.item(item));
322271
}
323272

324273
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
274+
self.insert_nested(item_id.def_id);
325275
self.visit_trait_item(self.krate.trait_item(item_id));
326276
}
327277

328278
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
279+
self.insert_nested(item_id.def_id);
329280
self.visit_impl_item(self.krate.impl_item(item_id));
330281
}
331282

332283
fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) {
284+
self.insert_nested(foreign_id.def_id);
333285
self.visit_foreign_item(self.krate.foreign_item(foreign_id));
334286
}
335287

@@ -517,6 +469,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
517469
self.definitions.local_def_id_to_hir_id(LocalDefId { local_def_index })
518470
});
519471
self.with_parent(parent, |this| {
472+
this.insert_nested(macro_def.def_id);
520473
this.with_dep_node_owner(macro_def.def_id, macro_def, |this, hash| {
521474
this.insert_with_hash(
522475
macro_def.span,

0 commit comments

Comments
 (0)