@@ -20,84 +20,6 @@ pub use crate::def_id::DefPathHash;
2020use crate :: def_id:: { CRATE_DEF_INDEX , CrateNum , DefIndex , LOCAL_CRATE , LocalDefId , StableCrateId } ;
2121use 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 ) ]
10224pub 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 ) ]
13049pub 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
326248impl 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
0 commit comments