Skip to content

Commit 29d6359

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 + ea544d2 commit 29d6359

4 files changed

Lines changed: 79 additions & 113 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: 72 additions & 106 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,23 +246,26 @@ pub enum DefPathData {
324246
}
325247

326248
impl Definitions {
327-
pub fn def_path_table(&self) -> &DefPathTable {
328-
&self.table
249+
#[inline(always)]
250+
pub fn def_key(&self, id: LocalDefId) -> DefKey {
251+
self.def_key_by_index(id.local_def_index)
329252
}
330253

331-
/// Gets the number of definitions.
332-
pub fn def_index_count(&self) -> usize {
333-
self.table.index_to_key.len()
254+
#[inline(always)]
255+
pub fn def_key_by_index(&self, index: DefIndex) -> DefKey {
256+
self.table[index].0
334257
}
335258

336-
#[inline]
337-
pub fn def_key(&self, id: LocalDefId) -> DefKey {
338-
self.table.def_key(id.local_def_index)
259+
#[instrument(level = "trace", skip(self), ret)]
260+
#[inline(always)]
261+
pub fn def_path_hash(&self, id: LocalDefId) -> DefPathHash {
262+
self.def_path_hash_by_index(id.local_def_index)
339263
}
340264

341265
#[inline(always)]
342-
pub fn def_path_hash(&self, id: LocalDefId) -> DefPathHash {
343-
self.table.def_path_hash(id.local_def_index)
266+
pub fn def_path_hash_by_index(&self, index: DefIndex) -> DefPathHash {
267+
let hash = self.table[index].1;
268+
DefPathHash::new(self.stable_crate_id, hash)
344269
}
345270

346271
/// Returns the path from the crate root to `index`. The root
@@ -349,9 +274,7 @@ impl Definitions {
349274
/// will be the path of the item in the external crate (but the
350275
/// path will begin with the path to the external crate).
351276
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-
})
277+
DefPath::make(LOCAL_CRATE, id.local_def_index, |index| self.def_key_by_index(index))
355278
}
356279

357280
/// Adds a root definition (no parent) and a few other reserved definitions.
@@ -376,11 +299,55 @@ impl Definitions {
376299
DefPathHash::new(stable_crate_id, Hash64::new(stable_crate_id.as_u64()));
377300

378301
// 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) };
302+
let mut defs = Definitions {
303+
stable_crate_id,
304+
table: Default::default(),
305+
def_path_hash_to_index: Default::default(),
306+
};
307+
308+
let root = LocalDefId { local_def_index: defs.allocate(key, def_path_hash) };
381309
assert_eq!(root.local_def_index, CRATE_DEF_INDEX);
382310

383-
Definitions { table }
311+
defs
312+
}
313+
314+
fn allocate(&mut self, key: DefKey, def_path_hash: DefPathHash) -> DefIndex {
315+
// Assert that all DefPathHashes correctly contain the local crate's StableCrateId.
316+
debug_assert_eq!(self.stable_crate_id, def_path_hash.stable_crate_id());
317+
let local_hash = def_path_hash.local_hash();
318+
319+
let index = self.table.push((key, local_hash));
320+
debug!("Definitions::insert() - {key:?} <-> {index:?}");
321+
322+
// Check for hash collisions of DefPathHashes. These should be
323+
// exceedingly rare.
324+
if let Some(existing) = self.def_path_hash_to_index.insert(&local_hash, &index) {
325+
let def_path1 = DefPath::make(LOCAL_CRATE, existing, |idx| self.def_key_by_index(idx));
326+
let def_path2 = DefPath::make(LOCAL_CRATE, index, |idx| self.def_key_by_index(idx));
327+
328+
// Continuing with colliding DefPathHashes can lead to correctness
329+
// issues. We must abort compilation.
330+
//
331+
// The likelihood of such a collision is very small, so actually
332+
// running into one could be indicative of a poor hash function
333+
// being used.
334+
//
335+
// See the documentation for DefPathHash for more information.
336+
panic!(
337+
"found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
338+
Compilation cannot continue."
339+
);
340+
}
341+
342+
index
343+
}
344+
345+
pub fn enumerated_keys_and_path_hashes(
346+
&self,
347+
) -> impl Iterator<Item = (DefIndex, &DefKey, DefPathHash)> + ExactSizeIterator {
348+
self.table
349+
.iter_enumerated()
350+
.map(move |(index, (key, _))| (index, key, self.def_path_hash_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: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -510,18 +510,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
510510
}
511511

512512
fn encode_def_path_table(&mut self) {
513-
let table = self.tcx.def_path_table();
513+
let defs = self.tcx.definitions();
514514
if self.is_proc_macro {
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(defs.def_key_by_index(def_index));
519+
let def_path_hash = defs.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
}
523523
} else {
524-
for (def_index, def_key, def_path_hash) in table.enumerated_keys_and_path_hashes() {
524+
for (def_index, def_key, def_path_hash) in defs.enumerated_keys_and_path_hashes() {
525525
let def_key = self.lazy(def_key);
526526
self.tables.def_keys.set_some(def_index, def_key);
527527
self.tables.def_path_hashes.set(def_index, def_path_hash.local_hash().as_u64());

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 definitions(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)