Skip to content

Commit 6349cc5

Browse files
committed
Auto merge of #156963 - aerooneqq:defs-refactoring, r=<try>
definitions: remove `DefPathTable`, merge `index_to_key` and `def_path_hashes`
2 parents b7e97a9 + 4490f21 commit 6349cc5

4 files changed

Lines changed: 94 additions & 128 deletions

File tree

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {
542542
let ast_index = index_crate(&resolver, &krate);
543543
let mut owners = IndexVec::from_fn_n(
544544
|_| hir::MaybeOwner::Phantom,
545-
tcx.definitions_untracked().def_index_count(),
545+
tcx.definitions_untracked().num_definitions(),
546546
);
547547

548548
let mut lowerer = item::ItemLowerer {

compiler/rustc_hir/src/definitions.rs

Lines changed: 89 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -20,84 +20,6 @@ pub use crate::def_id::DefPathHash;
2020
use crate::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, LOCAL_CRATE, LocalDefId, StableCrateId};
2121
use crate::def_path_hash_map::DefPathHashMap;
2222

23-
/// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
24-
/// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
25-
/// stores the `DefIndex` of its parent.
26-
/// There is one `DefPathTable` for each crate.
27-
#[derive(Debug)]
28-
pub struct DefPathTable {
29-
stable_crate_id: StableCrateId,
30-
index_to_key: IndexVec<DefIndex, DefKey>,
31-
// We do only store the local hash, as all the definitions are from the current crate.
32-
def_path_hashes: IndexVec<DefIndex, Hash64>,
33-
def_path_hash_to_index: DefPathHashMap,
34-
}
35-
36-
impl DefPathTable {
37-
fn new(stable_crate_id: StableCrateId) -> DefPathTable {
38-
DefPathTable {
39-
stable_crate_id,
40-
index_to_key: Default::default(),
41-
def_path_hashes: Default::default(),
42-
def_path_hash_to_index: Default::default(),
43-
}
44-
}
45-
46-
fn allocate(&mut self, key: DefKey, def_path_hash: DefPathHash) -> DefIndex {
47-
// Assert that all DefPathHashes correctly contain the local crate's StableCrateId.
48-
debug_assert_eq!(self.stable_crate_id, def_path_hash.stable_crate_id());
49-
let local_hash = def_path_hash.local_hash();
50-
51-
let index = self.index_to_key.push(key);
52-
debug!("DefPathTable::insert() - {key:?} <-> {index:?}");
53-
54-
self.def_path_hashes.push(local_hash);
55-
debug_assert!(self.def_path_hashes.len() == self.index_to_key.len());
56-
57-
// Check for hash collisions of DefPathHashes. These should be
58-
// exceedingly rare.
59-
if let Some(existing) = self.def_path_hash_to_index.insert(&local_hash, &index) {
60-
let def_path1 = DefPath::make(LOCAL_CRATE, existing, |idx| self.def_key(idx));
61-
let def_path2 = DefPath::make(LOCAL_CRATE, index, |idx| self.def_key(idx));
62-
63-
// Continuing with colliding DefPathHashes can lead to correctness
64-
// issues. We must abort compilation.
65-
//
66-
// The likelihood of such a collision is very small, so actually
67-
// running into one could be indicative of a poor hash function
68-
// being used.
69-
//
70-
// See the documentation for DefPathHash for more information.
71-
panic!(
72-
"found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
73-
Compilation cannot continue."
74-
);
75-
}
76-
77-
index
78-
}
79-
80-
#[inline(always)]
81-
pub fn def_key(&self, index: DefIndex) -> DefKey {
82-
self.index_to_key[index]
83-
}
84-
85-
#[instrument(level = "trace", skip(self), ret)]
86-
#[inline(always)]
87-
pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
88-
let hash = self.def_path_hashes[index];
89-
DefPathHash::new(self.stable_crate_id, hash)
90-
}
91-
92-
pub fn enumerated_keys_and_path_hashes(
93-
&self,
94-
) -> impl Iterator<Item = (DefIndex, &DefKey, DefPathHash)> + ExactSizeIterator {
95-
self.index_to_key
96-
.iter_enumerated()
97-
.map(move |(index, key)| (index, key, self.def_path_hash(index)))
98-
}
99-
}
100-
10123
#[derive(Debug, Default, Clone)]
10224
pub struct PerParentDisambiguatorState {
10325
#[cfg(debug_assertions)]
@@ -123,12 +45,12 @@ impl LocalDefIdMap<PerParentDisambiguatorState> {
12345
}
12446
}
12547

126-
/// The definition table containing node definitions.
127-
/// It holds the `DefPathTable` for `LocalDefId`s/`DefPath`s.
128-
/// It also stores mappings to convert `LocalDefId`s to/from `HirId`s.
12948
#[derive(Debug)]
13049
pub struct Definitions {
131-
table: DefPathTable,
50+
stable_crate_id: StableCrateId,
51+
// We do only store the local hash, as all the definitions are from the current crate.
52+
table: IndexVec<DefIndex, (DefKey, Hash64)>,
53+
def_path_hash_to_index: DefPathHashMap,
13254
}
13355

13456
/// A unique identifier that we can use to lookup a definition
@@ -167,7 +89,7 @@ impl DefKey {
16789
// Construct the new DefPathHash, making sure that the `crate_id`
16890
// portion of the hash is properly copied from the parent. This way the
16991
// `crate_id` part will be recursively propagated from the root to all
170-
// DefPathHashes in this DefPathTable.
92+
// DefPathHashes in this Definitions.
17193
DefPathHash::new(parent.stable_crate_id(), local_hash)
17294
}
17395

@@ -324,36 +246,6 @@ pub enum DefPathData {
324246
}
325247

326248
impl Definitions {
327-
pub fn def_path_table(&self) -> &DefPathTable {
328-
&self.table
329-
}
330-
331-
/// Gets the number of definitions.
332-
pub fn def_index_count(&self) -> usize {
333-
self.table.index_to_key.len()
334-
}
335-
336-
#[inline]
337-
pub fn def_key(&self, id: LocalDefId) -> DefKey {
338-
self.table.def_key(id.local_def_index)
339-
}
340-
341-
#[inline(always)]
342-
pub fn def_path_hash(&self, id: LocalDefId) -> DefPathHash {
343-
self.table.def_path_hash(id.local_def_index)
344-
}
345-
346-
/// Returns the path from the crate root to `index`. The root
347-
/// nodes are not included in the path (i.e., this will be an
348-
/// empty vector for the crate root). For an inlined item, this
349-
/// will be the path of the item in the external crate (but the
350-
/// path will begin with the path to the external crate).
351-
pub fn def_path(&self, id: LocalDefId) -> DefPath {
352-
DefPath::make(LOCAL_CRATE, id.local_def_index, |index| {
353-
self.def_key(LocalDefId { local_def_index: index })
354-
})
355-
}
356-
357249
/// Adds a root definition (no parent) and a few other reserved definitions.
358250
pub fn new(stable_crate_id: StableCrateId) -> Definitions {
359251
let key = DefKey {
@@ -376,11 +268,86 @@ impl Definitions {
376268
DefPathHash::new(stable_crate_id, Hash64::new(stable_crate_id.as_u64()));
377269

378270
// Create the root definition.
379-
let mut table = DefPathTable::new(stable_crate_id);
380-
let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) };
271+
let mut defs = Definitions {
272+
stable_crate_id,
273+
table: Default::default(),
274+
def_path_hash_to_index: Default::default(),
275+
};
276+
277+
let root = LocalDefId { local_def_index: defs.allocate(key, def_path_hash) };
381278
assert_eq!(root.local_def_index, CRATE_DEF_INDEX);
382279

383-
Definitions { table }
280+
defs
281+
}
282+
283+
fn allocate(&mut self, key: DefKey, def_path_hash: DefPathHash) -> DefIndex {
284+
// Assert that all DefPathHashes correctly contain the local crate's StableCrateId.
285+
debug_assert_eq!(self.stable_crate_id, def_path_hash.stable_crate_id());
286+
let local_hash = def_path_hash.local_hash();
287+
288+
let index = self.table.push((key, local_hash));
289+
debug!("Definitions::insert() - {key:?} <-> {index:?}");
290+
291+
// Check for hash collisions of DefPathHashes. These should be
292+
// exceedingly rare.
293+
if let Some(existing) = self.def_path_hash_to_index.insert(&local_hash, &index) {
294+
let def_path1 = DefPath::make(LOCAL_CRATE, existing, |idx| self.def_key_by_index(idx));
295+
let def_path2 = DefPath::make(LOCAL_CRATE, index, |idx| self.def_key_by_index(idx));
296+
297+
// Continuing with colliding DefPathHashes can lead to correctness
298+
// issues. We must abort compilation.
299+
//
300+
// The likelihood of such a collision is very small, so actually
301+
// running into one could be indicative of a poor hash function
302+
// being used.
303+
//
304+
// See the documentation for DefPathHash for more information.
305+
panic!(
306+
"found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
307+
Compilation cannot continue."
308+
);
309+
}
310+
311+
index
312+
}
313+
314+
#[inline(always)]
315+
pub fn def_key(&self, id: LocalDefId) -> DefKey {
316+
self.def_key_by_index(id.local_def_index)
317+
}
318+
319+
#[inline(always)]
320+
pub fn def_key_by_index(&self, index: DefIndex) -> DefKey {
321+
self.table[index].0
322+
}
323+
324+
#[instrument(level = "trace", skip(self), ret)]
325+
#[inline(always)]
326+
pub fn def_path_hash(&self, id: LocalDefId) -> DefPathHash {
327+
self.def_path_hash_by_index(id.local_def_index)
328+
}
329+
330+
#[inline(always)]
331+
pub fn def_path_hash_by_index(&self, index: DefIndex) -> DefPathHash {
332+
let hash = self.table[index].1;
333+
DefPathHash::new(self.stable_crate_id, hash)
334+
}
335+
336+
pub fn enumerated_keys_and_path_hashes(
337+
&self,
338+
) -> impl Iterator<Item = (DefIndex, &DefKey, DefPathHash)> + ExactSizeIterator {
339+
self.table
340+
.iter_enumerated()
341+
.map(move |(index, (key, _))| (index, key, self.def_path_hash_by_index(index)))
342+
}
343+
344+
/// Returns the path from the crate root to `index`. The root
345+
/// nodes are not included in the path (i.e., this will be an
346+
/// empty vector for the crate root). For an inlined item, this
347+
/// will be the path of the item in the external crate (but the
348+
/// path will begin with the path to the external crate).
349+
pub fn def_path(&self, id: LocalDefId) -> DefPath {
350+
DefPath::make(LOCAL_CRATE, id.local_def_index, |index| self.def_key_by_index(index))
384351
}
385352

386353
/// Creates a definition with a parent definition.
@@ -423,13 +390,13 @@ impl Definitions {
423390
disambiguated_data: DisambiguatedDefPathData { data, disambiguator },
424391
};
425392

426-
let parent_hash = self.table.def_path_hash(parent.local_def_index);
393+
let parent_hash = self.def_path_hash_by_index(parent.local_def_index);
427394
let def_path_hash = key.compute_stable_hash(parent_hash);
428395

429396
debug!("create_def: after disambiguation, key = {:?}", key);
430397

431398
// Create the definition.
432-
LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) }
399+
LocalDefId { local_def_index: self.allocate(key, def_path_hash) }
433400
}
434401

435402
#[inline(always)]
@@ -439,19 +406,18 @@ impl Definitions {
439406
/// if the `DefPathHash` is from a previous compilation session and
440407
/// the def-path does not exist anymore.
441408
pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option<LocalDefId> {
442-
debug_assert!(hash.stable_crate_id() == self.table.stable_crate_id);
443-
self.table
444-
.def_path_hash_to_index
409+
debug_assert!(hash.stable_crate_id() == self.stable_crate_id);
410+
self.def_path_hash_to_index
445411
.get(&hash.local_hash())
446412
.map(|local_def_index| LocalDefId { local_def_index })
447413
}
448414

449415
pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap {
450-
&self.table.def_path_hash_to_index
416+
&self.def_path_hash_to_index
451417
}
452418

453419
pub fn num_definitions(&self) -> usize {
454-
self.table.def_path_hashes.len()
420+
self.table.len()
455421
}
456422
}
457423

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
515515
for def_index in std::iter::once(CRATE_DEF_INDEX)
516516
.chain(self.tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index))
517517
{
518-
let def_key = self.lazy(table.def_key(def_index));
519-
let def_path_hash = table.def_path_hash(def_index);
518+
let def_key = self.lazy(table.def_key_by_index(def_index));
519+
let def_path_hash = table.def_path_hash_by_index(def_index);
520520
self.tables.def_keys.set_some(def_index, def_key);
521521
self.tables.def_path_hashes.set(def_index, def_path_hash.local_hash().as_u64());
522522
}

compiler/rustc_middle/src/ty/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,13 +1343,13 @@ impl<'tcx> TyCtxt<'tcx> {
13431343
}
13441344
}
13451345

1346-
pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable {
1346+
pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::Definitions {
13471347
// Depend on the `analysis` query to ensure compilation if finished.
13481348
self.ensure_ok().analysis(());
13491349

13501350
// Freeze definitions once we start iterating on them, to prevent adding new ones
13511351
// while iterating. If some query needs to add definitions, it should be `ensure`d above.
1352-
self.untracked.definitions.freeze().def_path_table()
1352+
self.untracked.definitions.freeze()
13531353
}
13541354

13551355
pub fn def_path_hash_to_def_index_map(

0 commit comments

Comments
 (0)