5
5
//! expressions) that are mostly just leftovers.
6
6
7
7
pub use crate :: def_id:: DefPathHash ;
8
- use crate :: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
8
+ use crate :: def_id:: {
9
+ CrateNum , DefId , DefIndex , LocalDefId , StableCrateId , CRATE_DEF_INDEX , LOCAL_CRATE ,
10
+ } ;
9
11
use crate :: hir;
10
12
11
- use rustc_ast:: crate_disambiguator:: CrateDisambiguator ;
12
13
use rustc_data_structures:: fx:: FxHashMap ;
13
14
use rustc_data_structures:: stable_hasher:: StableHasher ;
15
+ use rustc_data_structures:: unhash:: UnhashMap ;
14
16
use rustc_index:: vec:: IndexVec ;
17
+ use rustc_span:: crate_disambiguator:: CrateDisambiguator ;
15
18
use rustc_span:: hygiene:: ExpnId ;
16
19
use rustc_span:: symbol:: { kw, sym, Symbol } ;
17
20
@@ -27,6 +30,7 @@ use tracing::debug;
27
30
pub struct DefPathTable {
28
31
index_to_key : IndexVec < DefIndex , DefKey > ,
29
32
def_path_hashes : IndexVec < DefIndex , DefPathHash > ,
33
+ def_path_hash_to_index : UnhashMap < DefPathHash , DefIndex > ,
30
34
}
31
35
32
36
impl DefPathTable {
@@ -39,6 +43,25 @@ impl DefPathTable {
39
43
} ;
40
44
self . def_path_hashes . push ( def_path_hash) ;
41
45
debug_assert ! ( self . def_path_hashes. len( ) == self . index_to_key. len( ) ) ;
46
+
47
+ // Check for hash collisions of DefPathHashes. These should be
48
+ // exceedingly rare.
49
+ if let Some ( existing) = self . def_path_hash_to_index . insert ( def_path_hash, index) {
50
+ let def_path1 = DefPath :: make ( LOCAL_CRATE , existing, |idx| self . def_key ( idx) ) ;
51
+ let def_path2 = DefPath :: make ( LOCAL_CRATE , index, |idx| self . def_key ( idx) ) ;
52
+
53
+ // Continuing with colliding DefPathHashes can lead to correctness
54
+ // issues. We must abort compilation.
55
+ panic ! ( "Found DefPathHash collsion between {:?} and {:?}" , def_path1, def_path2) ;
56
+ }
57
+
58
+ // Assert that all DefPathHashes correctly contain the local crate's
59
+ // StableCrateId
60
+ #[ cfg( debug_assertions) ]
61
+ if let Some ( root) = self . def_path_hashes . get ( CRATE_DEF_INDEX ) {
62
+ assert ! ( def_path_hash. stable_crate_id( ) == root. stable_crate_id( ) ) ;
63
+ }
64
+
42
65
index
43
66
}
44
67
@@ -108,13 +131,10 @@ pub struct DefKey {
108
131
}
109
132
110
133
impl DefKey {
111
- fn compute_stable_hash ( & self , parent_hash : DefPathHash ) -> DefPathHash {
134
+ fn compute_stable_hash ( & self , parent : DefPathHash ) -> DefPathHash {
112
135
let mut hasher = StableHasher :: new ( ) ;
113
136
114
- // We hash a `0u8` here to disambiguate between regular `DefPath` hashes,
115
- // and the special "root_parent" below.
116
- 0u8 . hash ( & mut hasher) ;
117
- parent_hash. hash ( & mut hasher) ;
137
+ parent. hash ( & mut hasher) ;
118
138
119
139
let DisambiguatedDefPathData { ref data, disambiguator } = self . disambiguated_data ;
120
140
@@ -127,19 +147,13 @@ impl DefKey {
127
147
128
148
disambiguator. hash ( & mut hasher) ;
129
149
130
- DefPathHash ( hasher. finish ( ) )
131
- }
150
+ let local_hash: u64 = hasher. finish ( ) ;
132
151
133
- fn root_parent_stable_hash (
134
- crate_name : & str ,
135
- crate_disambiguator : CrateDisambiguator ,
136
- ) -> DefPathHash {
137
- let mut hasher = StableHasher :: new ( ) ;
138
- // Disambiguate this from a regular `DefPath` hash; see `compute_stable_hash()` above.
139
- 1u8 . hash ( & mut hasher) ;
140
- crate_name. hash ( & mut hasher) ;
141
- crate_disambiguator. hash ( & mut hasher) ;
142
- DefPathHash ( hasher. finish ( ) )
152
+ // Construct the new DefPathHash, making sure that the `crate_id`
153
+ // portion of the hash is properly copied from the parent. This way the
154
+ // `crate_id` part will be recursively propagated from the root to all
155
+ // DefPathHashes in this DefPathTable.
156
+ DefPathHash :: new ( parent. stable_crate_id ( ) , local_hash)
143
157
}
144
158
}
145
159
@@ -295,6 +309,12 @@ impl Definitions {
295
309
self . table . def_path_hash ( id. local_def_index )
296
310
}
297
311
312
+ #[ inline]
313
+ pub fn def_path_hash_to_def_id ( & self , def_path_hash : DefPathHash ) -> LocalDefId {
314
+ let local_def_index = self . table . def_path_hash_to_index [ & def_path_hash] ;
315
+ LocalDefId { local_def_index }
316
+ }
317
+
298
318
/// Returns the path from the crate root to `index`. The root
299
319
/// nodes are not included in the path (i.e., this will be an
300
320
/// empty vector for the crate root). For an inlined item, this
@@ -332,7 +352,8 @@ impl Definitions {
332
352
} ,
333
353
} ;
334
354
335
- let parent_hash = DefKey :: root_parent_stable_hash ( crate_name, crate_disambiguator) ;
355
+ let stable_crate_id = StableCrateId :: new ( crate_name, crate_disambiguator) ;
356
+ let parent_hash = DefPathHash :: new ( stable_crate_id, 0 ) ;
336
357
let def_path_hash = key. compute_stable_hash ( parent_hash) ;
337
358
338
359
// Create the root definition.
0 commit comments