Skip to content

Commit bd41e09

Browse files
committed
Auto merge of #89124 - cjgillot:owner-info, r=michaelwoerister
Index and hash HIR as part of lowering Part of #88186 ~Based on #88880 (see merge commit).~ Once HIR is lowered, it is later indexed by the `index_hir` query and hashed for `crate_hash`. This PR moves those post-processing steps to lowering itself. As a side objective, the HIR crate data structure is refactored as an `IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>` where `OwnerInfo` stores all the relevant information for an HIR owner. r? `@michaelwoerister` cc `@petrochenkov`
2 parents 5dab47d + 1e2dbb5 commit bd41e09

File tree

28 files changed

+547
-594
lines changed

28 files changed

+547
-594
lines changed

Cargo.lock

+3
Original file line numberDiff line numberDiff line change
@@ -3568,6 +3568,7 @@ dependencies = [
35683568
"rustc_errors",
35693569
"rustc_hir",
35703570
"rustc_index",
3571+
"rustc_query_system",
35713572
"rustc_session",
35723573
"rustc_span",
35733574
"rustc_target",
@@ -4102,6 +4103,7 @@ dependencies = [
41024103
"polonius-engine",
41034104
"rand 0.8.4",
41044105
"rand_xoshiro 0.6.0",
4106+
"rustc-rayon",
41054107
"rustc-rayon-core",
41064108
"rustc_apfloat",
41074109
"rustc_arena",
@@ -4346,6 +4348,7 @@ dependencies = [
43464348
"rustc_index",
43474349
"rustc_metadata",
43484350
"rustc_middle",
4351+
"rustc_query_system",
43494352
"rustc_session",
43504353
"rustc_span",
43514354
"smallvec",

compiler/rustc_ast_lowering/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ rustc_hir = { path = "../rustc_hir" }
1414
rustc_target = { path = "../rustc_target" }
1515
rustc_data_structures = { path = "../rustc_data_structures" }
1616
rustc_index = { path = "../rustc_index" }
17+
rustc_query_system = { path = "../rustc_query_system" }
1718
rustc_span = { path = "../rustc_span" }
1819
rustc_errors = { path = "../rustc_errors" }
1920
rustc_session = { path = "../rustc_session" }

compiler/rustc_ast_lowering/src/expr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
252252
}
253253
// Merge attributes into the inner expression.
254254
if !e.attrs.is_empty() {
255-
let old_attrs = self.attrs.get(&ex.hir_id).map(|la| *la).unwrap_or(&[]);
255+
let old_attrs =
256+
self.attrs.get(&ex.hir_id.local_id).map(|la| *la).unwrap_or(&[]);
256257
self.attrs.insert(
257-
ex.hir_id,
258+
ex.hir_id.local_id,
258259
&*self.arena.alloc_from_iter(
259260
e.attrs
260261
.iter()

compiler/rustc_middle/src/hir/map/collector.rs renamed to compiler/rustc_ast_lowering/src/index.rs

+63-130
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,33 @@
1-
use crate::arena::Arena;
2-
use crate::hir::map::Map;
3-
use crate::hir::{IndexedHir, OwnerNodes, ParentedNode};
4-
use rustc_data_structures::fingerprint::Fingerprint;
51
use rustc_data_structures::fx::FxHashMap;
6-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
72
use rustc_hir as hir;
83
use rustc_hir::def_id::LocalDefId;
9-
use rustc_hir::def_id::CRATE_DEF_ID;
104
use rustc_hir::definitions;
115
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
126
use rustc_hir::*;
137
use rustc_index::vec::{Idx, IndexVec};
14-
use rustc_query_system::ich::StableHashingContext;
158
use rustc_session::Session;
169
use rustc_span::source_map::SourceMap;
1710
use rustc_span::{Span, DUMMY_SP};
1811

1912
use std::iter::repeat;
13+
use tracing::debug;
2014

2115
/// A visitor that walks over the HIR and collects `Node`s into a HIR map.
2216
pub(super) struct NodeCollector<'a, 'hir> {
23-
arena: &'hir Arena<'hir>,
24-
25-
/// The crate
26-
krate: &'hir Crate<'hir>,
27-
2817
/// Source map
2918
source_map: &'a SourceMap,
19+
bodies: &'a IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
3020

31-
map: IndexVec<LocalDefId, Option<&'hir mut OwnerNodes<'hir>>>,
32-
parenting: FxHashMap<LocalDefId, HirId>,
21+
/// Outputs
22+
nodes: IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>,
23+
parenting: FxHashMap<LocalDefId, ItemLocalId>,
3324

3425
/// The parent of this node
35-
parent_node: hir::HirId,
26+
parent_node: hir::ItemLocalId,
3627

37-
current_dep_node_owner: LocalDefId,
28+
owner: LocalDefId,
3829

3930
definitions: &'a definitions::Definitions,
40-
41-
hcx: StableHashingContext<'a>,
4231
}
4332

4433
fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V) {
@@ -51,137 +40,82 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
5140
map[k] = Some(v);
5241
}
5342

54-
fn hash_body(
55-
hcx: &mut StableHashingContext<'_>,
56-
item_like: impl for<'a> HashStable<StableHashingContext<'a>>,
57-
) -> Fingerprint {
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()
43+
pub(super) fn index_hir<'hir>(
44+
sess: &Session,
45+
definitions: &definitions::Definitions,
46+
item: hir::OwnerNode<'hir>,
47+
bodies: &IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
48+
) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, FxHashMap<LocalDefId, ItemLocalId>) {
49+
let mut nodes = IndexVec::new();
50+
// This node's parent should never be accessed: the owner's parent is computed by the
51+
// hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
52+
// used.
53+
nodes.push(Some(ParentedNode { parent: ItemLocalId::INVALID, node: item.into() }));
54+
let mut collector = NodeCollector {
55+
source_map: sess.source_map(),
56+
definitions,
57+
owner: item.def_id(),
58+
parent_node: ItemLocalId::new(0),
59+
nodes,
60+
bodies,
61+
parenting: FxHashMap::default(),
62+
};
63+
64+
match item {
65+
OwnerNode::Crate(citem) => collector.visit_mod(&citem, citem.inner, hir::CRATE_HIR_ID),
66+
OwnerNode::Item(item) => collector.visit_item(item),
67+
OwnerNode::TraitItem(item) => collector.visit_trait_item(item),
68+
OwnerNode::ImplItem(item) => collector.visit_impl_item(item),
69+
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
70+
};
71+
72+
(collector.nodes, collector.parenting)
6373
}
6474

6575
impl<'a, 'hir> NodeCollector<'a, 'hir> {
66-
pub(super) fn root(
67-
sess: &'a Session,
68-
arena: &'hir Arena<'hir>,
69-
krate: &'hir Crate<'hir>,
70-
definitions: &'a definitions::Definitions,
71-
hcx: StableHashingContext<'a>,
72-
) -> NodeCollector<'a, 'hir> {
73-
let mut collector = NodeCollector {
74-
arena,
75-
krate,
76-
source_map: sess.source_map(),
77-
parent_node: hir::CRATE_HIR_ID,
78-
current_dep_node_owner: CRATE_DEF_ID,
79-
definitions,
80-
hcx,
81-
map: IndexVec::from_fn_n(|_| None, definitions.def_index_count()),
82-
parenting: FxHashMap::default(),
83-
};
84-
collector.insert_owner(CRATE_DEF_ID, OwnerNode::Crate(krate.module()));
85-
86-
collector
87-
}
88-
89-
pub(super) fn finalize_and_compute_crate_hash(mut self) -> IndexedHir<'hir> {
90-
// Insert bodies into the map
91-
for (id, body) in self.krate.bodies.iter() {
92-
let bodies = &mut self.map[id.hir_id.owner].as_mut().unwrap().bodies;
93-
assert!(bodies.insert(id.hir_id.local_id, body).is_none());
94-
}
95-
IndexedHir { map: self.map, parenting: self.parenting }
96-
}
97-
98-
fn insert_owner(&mut self, owner: LocalDefId, node: OwnerNode<'hir>) {
99-
let hash = hash_body(&mut self.hcx, node);
100-
101-
let mut nodes = IndexVec::new();
102-
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
103-
104-
debug_assert!(self.map[owner].is_none());
105-
self.map[owner] =
106-
Some(self.arena.alloc(OwnerNodes { hash, nodes, bodies: FxHashMap::default() }));
107-
}
108-
10976
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
110-
debug_assert_eq!(self.current_dep_node_owner, hir_id.owner);
77+
debug_assert_eq!(self.owner, hir_id.owner);
11178
debug_assert_ne!(hir_id.local_id.as_u32(), 0);
11279

11380
// Make sure that the DepNode of some node coincides with the HirId
11481
// owner of that node.
11582
if cfg!(debug_assertions) {
116-
if hir_id.owner != self.current_dep_node_owner {
117-
let node_str = match self.definitions.opt_hir_id_to_local_def_id(hir_id) {
118-
Some(def_id) => self.definitions.def_path(def_id).to_string_no_crate_verbose(),
119-
None => format!("{:?}", node),
120-
};
121-
122-
span_bug!(
123-
span,
124-
"inconsistent DepNode at `{:?}` for `{}`: \
83+
if hir_id.owner != self.owner {
84+
panic!(
85+
"inconsistent DepNode at `{:?}` for `{:?}`: \
12586
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
12687
self.source_map.span_to_diagnostic_string(span),
127-
node_str,
128-
self.definitions
129-
.def_path(self.current_dep_node_owner)
130-
.to_string_no_crate_verbose(),
131-
self.current_dep_node_owner,
88+
node,
89+
self.definitions.def_path(self.owner).to_string_no_crate_verbose(),
90+
self.owner,
13291
self.definitions.def_path(hir_id.owner).to_string_no_crate_verbose(),
13392
hir_id.owner,
13493
)
13594
}
13695
}
13796

138-
let nodes = self.map[hir_id.owner].as_mut().unwrap();
139-
140-
debug_assert_eq!(self.parent_node.owner, self.current_dep_node_owner);
14197
insert_vec_map(
142-
&mut nodes.nodes,
98+
&mut self.nodes,
14399
hir_id.local_id,
144-
ParentedNode { parent: self.parent_node.local_id, node: node },
100+
ParentedNode { parent: self.parent_node, node: node },
145101
);
146102
}
147103

148104
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
105+
debug_assert_eq!(parent_node_id.owner, self.owner);
149106
let parent_node = self.parent_node;
150-
self.parent_node = parent_node_id;
107+
self.parent_node = parent_node_id.local_id;
151108
f(self);
152109
self.parent_node = parent_node;
153110
}
154111

155-
fn with_dep_node_owner(&mut self, dep_node_owner: LocalDefId, f: impl FnOnce(&mut Self)) {
156-
let prev_owner = self.current_dep_node_owner;
157-
let prev_parent = self.parent_node;
158-
159-
self.current_dep_node_owner = dep_node_owner;
160-
self.parent_node = HirId::make_owner(dep_node_owner);
161-
f(self);
162-
self.current_dep_node_owner = prev_owner;
163-
self.parent_node = prev_parent;
164-
}
165-
166112
fn insert_nested(&mut self, item: LocalDefId) {
167-
#[cfg(debug_assertions)]
168-
{
169-
let dk_parent = self.definitions.def_key(item).parent.unwrap();
170-
let dk_parent = LocalDefId { local_def_index: dk_parent };
171-
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
172-
debug_assert_eq!(
173-
dk_parent.owner, self.parent_node.owner,
174-
"Different parents for {:?}",
175-
item
176-
)
177-
}
178-
179-
assert_eq!(self.parenting.insert(item, self.parent_node), None);
113+
self.parenting.insert(item, self.parent_node);
180114
}
181115
}
182116

183117
impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
184-
type Map = Map<'hir>;
118+
type Map = !;
185119

186120
/// Because we want to track parent items and so forth, enable
187121
/// deep walking so that we walk nested items in the context of
@@ -194,26 +128,24 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
194128
fn visit_nested_item(&mut self, item: ItemId) {
195129
debug!("visit_nested_item: {:?}", item);
196130
self.insert_nested(item.def_id);
197-
self.visit_item(self.krate.item(item));
198131
}
199132

200133
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
201134
self.insert_nested(item_id.def_id);
202-
self.visit_trait_item(self.krate.trait_item(item_id));
203135
}
204136

205137
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
206138
self.insert_nested(item_id.def_id);
207-
self.visit_impl_item(self.krate.impl_item(item_id));
208139
}
209140

210141
fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) {
211142
self.insert_nested(foreign_id.def_id);
212-
self.visit_foreign_item(self.krate.foreign_item(foreign_id));
213143
}
214144

215145
fn visit_nested_body(&mut self, id: BodyId) {
216-
self.visit_body(self.krate.body(id));
146+
debug_assert_eq!(id.hir_id.owner, self.owner);
147+
let body = self.bodies[id.hir_id.local_id].unwrap();
148+
self.visit_body(body);
217149
}
218150

219151
fn visit_param(&mut self, param: &'hir Param<'hir>) {
@@ -226,8 +158,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
226158

227159
fn visit_item(&mut self, i: &'hir Item<'hir>) {
228160
debug!("visit_item: {:?}", i);
229-
self.insert_owner(i.def_id, OwnerNode::Item(i));
230-
self.with_dep_node_owner(i.def_id, |this| {
161+
debug_assert_eq!(i.def_id, self.owner);
162+
self.with_parent(i.hir_id(), |this| {
231163
if let ItemKind::Struct(ref struct_def, _) = i.kind {
232164
// If this is a tuple or unit-like struct, register the constructor.
233165
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
@@ -239,8 +171,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
239171
}
240172

241173
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
242-
self.insert_owner(fi.def_id, OwnerNode::ForeignItem(fi));
243-
self.with_dep_node_owner(fi.def_id, |this| {
174+
debug_assert_eq!(fi.def_id, self.owner);
175+
self.with_parent(fi.hir_id(), |this| {
244176
intravisit::walk_foreign_item(this, fi);
245177
});
246178
}
@@ -257,15 +189,15 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
257189
}
258190

259191
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
260-
self.insert_owner(ti.def_id, OwnerNode::TraitItem(ti));
261-
self.with_dep_node_owner(ti.def_id, |this| {
192+
debug_assert_eq!(ti.def_id, self.owner);
193+
self.with_parent(ti.hir_id(), |this| {
262194
intravisit::walk_trait_item(this, ti);
263195
});
264196
}
265197

266198
fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
267-
self.insert_owner(ii.def_id, OwnerNode::ImplItem(ii));
268-
self.with_dep_node_owner(ii.def_id, |this| {
199+
debug_assert_eq!(ii.def_id, self.owner);
200+
self.with_parent(ii.hir_id(), |this| {
269201
intravisit::walk_impl_item(this, ii);
270202
});
271203
}
@@ -353,7 +285,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
353285
s: Span,
354286
id: HirId,
355287
) {
356-
assert_eq!(self.parent_node, id);
288+
assert_eq!(self.owner, id.owner);
289+
assert_eq!(self.parent_node, id.local_id);
357290
intravisit::walk_fn(self, fk, fd, b, s, id);
358291
}
359292

0 commit comments

Comments
 (0)