Skip to content

Commit b8d9ef8

Browse files
Rollup merge of #156963 - aerooneqq:defs-refactoring, r=petrochenkov
definitions: remove `DefPathTable`, use `LocalDefId` instead of `DefIndex` This PR removes `DefPathTable` and uses `LocalDefId` instead of `DefIndex` where possible. r? @petrochenkov
2 parents e6541c4 + 7767295 commit b8d9ef8

4 files changed

Lines changed: 84 additions & 117 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: 70 additions & 105 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,13 @@ 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+
def_id_to_key: IndexVec<LocalDefId, DefKey>,
52+
// We do only store the local hash, as all the definitions are from the current crate.
53+
def_path_hashes: IndexVec<LocalDefId, Hash64>,
54+
def_path_hash_to_index: DefPathHashMap,
13255
}
13356

13457
/// A unique identifier that we can use to lookup a definition
@@ -167,7 +90,7 @@ impl DefKey {
16790
// Construct the new DefPathHash, making sure that the `crate_id`
16891
// portion of the hash is properly copied from the parent. This way the
16992
// `crate_id` part will be recursively propagated from the root to all
170-
// DefPathHashes in this DefPathTable.
93+
// DefPathHashes in this Definitions.
17194
DefPathHash::new(parent.stable_crate_id(), local_hash)
17295
}
17396

@@ -324,30 +247,23 @@ pub enum DefPathData {
324247
}
325248

326249
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]
250+
#[inline(always)]
337251
pub fn def_key(&self, id: LocalDefId) -> DefKey {
338-
self.table.def_key(id.local_def_index)
252+
self.def_id_to_key[id]
339253
}
340254

255+
#[instrument(level = "trace", skip(self), ret)]
341256
#[inline(always)]
342257
pub fn def_path_hash(&self, id: LocalDefId) -> DefPathHash {
343-
self.table.def_path_hash(id.local_def_index)
258+
DefPathHash::new(self.stable_crate_id, self.def_path_hashes[id])
344259
}
345260

346261
/// Returns the path from the crate root to `index`. The root
347262
/// nodes are not included in the path (i.e., this will be an
348263
/// empty vector for the crate root). For an inlined item, this
349264
/// will be the path of the item in the external crate (but the
350265
/// path will begin with the path to the external crate).
266+
#[inline]
351267
pub fn def_path(&self, id: LocalDefId) -> DefPath {
352268
DefPath::make(LOCAL_CRATE, id.local_def_index, |index| {
353269
self.def_key(LocalDefId { local_def_index: index })
@@ -375,12 +291,62 @@ impl Definitions {
375291
let def_path_hash =
376292
DefPathHash::new(stable_crate_id, Hash64::new(stable_crate_id.as_u64()));
377293

294+
let mut defs = Definitions {
295+
stable_crate_id,
296+
def_path_hashes: Default::default(),
297+
def_id_to_key: Default::default(),
298+
def_path_hash_to_index: Default::default(),
299+
};
300+
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 root = defs.allocate(key, def_path_hash);
381303
assert_eq!(root.local_def_index, CRATE_DEF_INDEX);
382304

383-
Definitions { table }
305+
defs
306+
}
307+
308+
fn allocate(&mut self, key: DefKey, def_path_hash: DefPathHash) -> LocalDefId {
309+
// Assert that all DefPathHashes correctly contain the local crate's StableCrateId.
310+
debug_assert_eq!(self.stable_crate_id, def_path_hash.stable_crate_id());
311+
let local_hash = def_path_hash.local_hash();
312+
313+
let def_id = self.def_id_to_key.push(key);
314+
debug!("def_id_to_key.push() - {key:?} <-> {:?}", def_id.local_def_index);
315+
316+
self.def_path_hashes.push(local_hash);
317+
debug_assert!(self.def_path_hashes.len() == self.def_id_to_key.len());
318+
319+
// Check for hash collisions of DefPathHashes. These should be
320+
// exceedingly rare.
321+
if let Some(existing) =
322+
self.def_path_hash_to_index.insert(&local_hash, &def_id.local_def_index)
323+
{
324+
let def_path1 = self.def_path(LocalDefId { local_def_index: existing });
325+
let def_path2 = self.def_path(def_id);
326+
327+
// Continuing with colliding DefPathHashes can lead to correctness
328+
// issues. We must abort compilation.
329+
//
330+
// The likelihood of such a collision is very small, so actually
331+
// running into one could be indicative of a poor hash function
332+
// being used.
333+
//
334+
// See the documentation for DefPathHash for more information.
335+
panic!(
336+
"found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
337+
Compilation cannot continue."
338+
);
339+
}
340+
341+
def_id
342+
}
343+
344+
pub fn enumerated_keys_and_path_hashes(
345+
&self,
346+
) -> impl Iterator<Item = (DefIndex, &DefKey, DefPathHash)> + ExactSizeIterator {
347+
self.def_id_to_key
348+
.iter_enumerated()
349+
.map(move |(def_id, key)| (def_id.local_def_index, key, self.def_path_hash(def_id)))
384350
}
385351

386352
/// Creates a definition with a parent definition.
@@ -423,13 +389,13 @@ impl Definitions {
423389
disambiguated_data: DisambiguatedDefPathData { data, disambiguator },
424390
};
425391

426-
let parent_hash = self.table.def_path_hash(parent.local_def_index);
392+
let parent_hash = self.def_path_hash(parent);
427393
let def_path_hash = key.compute_stable_hash(parent_hash);
428394

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

431397
// Create the definition.
432-
LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) }
398+
self.allocate(key, def_path_hash)
433399
}
434400

435401
#[inline(always)]
@@ -439,19 +405,18 @@ impl Definitions {
439405
/// if the `DefPathHash` is from a previous compilation session and
440406
/// the def-path does not exist anymore.
441407
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
408+
debug_assert!(hash.stable_crate_id() == self.stable_crate_id);
409+
self.def_path_hash_to_index
445410
.get(&hash.local_hash())
446411
.map(|local_def_index| LocalDefId { local_def_index })
447412
}
448413

449414
pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap {
450-
&self.table.def_path_hash_to_index
415+
&self.def_path_hash_to_index
451416
}
452417

453418
pub fn num_definitions(&self) -> usize {
454-
self.table.def_path_hashes.len()
419+
self.def_path_hashes.len()
455420
}
456421
}
457422

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_data_structures::temp_dir::MaybeTempDir;
1212
use rustc_data_structures::thousands::usize_with_underscores;
1313
use rustc_hir as hir;
1414
use rustc_hir::attrs::{AttributeKind, EncodeCrossCrate};
15-
use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE, LocalDefId, LocalDefIdSet};
15+
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalDefIdSet};
1616
use rustc_hir::definitions::DefPathData;
1717
use rustc_hir::find_attr;
1818
use rustc_hir_pretty::id_to_string;
@@ -510,18 +510,20 @@ 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 {
515-
for def_index in std::iter::once(CRATE_DEF_INDEX)
516-
.chain(self.tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index))
515+
for def_id in std::iter::once(CRATE_DEF_ID)
516+
.chain(self.tcx.resolutions(()).proc_macros.iter().copied())
517517
{
518-
let def_key = self.lazy(table.def_key(def_index));
519-
let def_path_hash = table.def_path_hash(def_index);
520-
self.tables.def_keys.set_some(def_index, def_key);
521-
self.tables.def_path_hashes.set(def_index, def_path_hash.local_hash().as_u64());
518+
let def_key = self.lazy(defs.def_key(def_id));
519+
let def_path_hash = defs.def_path_hash(def_id);
520+
self.tables.def_keys.set_some(def_id.local_def_index, def_key);
521+
self.tables
522+
.def_path_hashes
523+
.set(def_id.local_def_index, def_path_hash.local_hash().as_u64());
522524
}
523525
} else {
524-
for (def_index, def_key, def_path_hash) in table.enumerated_keys_and_path_hashes() {
526+
for (def_index, def_key, def_path_hash) in defs.enumerated_keys_and_path_hashes() {
525527
let def_key = self.lazy(def_key);
526528
self.tables.def_keys.set_some(def_index, def_key);
527529
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
@@ -1349,13 +1349,13 @@ impl<'tcx> TyCtxt<'tcx> {
13491349
}
13501350
}
13511351

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

13561356
// Freeze definitions once we start iterating on them, to prevent adding new ones
13571357
// while iterating. If some query needs to add definitions, it should be `ensure`d above.
1358-
self.untracked.definitions.freeze().def_path_table()
1358+
self.untracked.definitions.freeze()
13591359
}
13601360

13611361
pub fn def_path_hash_to_def_index_map(

0 commit comments

Comments
 (0)