@@ -21,7 +21,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
21
21
use rustc_data_structures:: stable_hasher:: StableHasher ;
22
22
use serialize:: { Encodable , Decodable , Encoder , Decoder } ;
23
23
use std:: fmt:: Write ;
24
- use std:: hash:: { Hash , Hasher } ;
24
+ use std:: hash:: Hash ;
25
25
use syntax:: ast;
26
26
use syntax:: symbol:: { Symbol , InternedString } ;
27
27
use ty:: TyCtxt ;
@@ -34,6 +34,7 @@ use util::nodemap::NodeMap;
34
34
pub struct DefPathTable {
35
35
index_to_key : [ Vec < DefKey > ; 2 ] ,
36
36
key_to_index : FxHashMap < DefKey , DefIndex > ,
37
+ def_path_hashes : [ Vec < u64 > ; 2 ] ,
37
38
}
38
39
39
40
// Unfortunately we have to provide a manual impl of Clone because of the
@@ -44,6 +45,8 @@ impl Clone for DefPathTable {
44
45
index_to_key : [ self . index_to_key [ 0 ] . clone ( ) ,
45
46
self . index_to_key [ 1 ] . clone ( ) ] ,
46
47
key_to_index : self . key_to_index . clone ( ) ,
48
+ def_path_hashes : [ self . def_path_hashes [ 0 ] . clone ( ) ,
49
+ self . def_path_hashes [ 1 ] . clone ( ) ] ,
47
50
}
48
51
}
49
52
}
@@ -52,6 +55,7 @@ impl DefPathTable {
52
55
53
56
fn allocate ( & mut self ,
54
57
key : DefKey ,
58
+ def_path_hash : u64 ,
55
59
address_space : DefIndexAddressSpace )
56
60
-> DefIndex {
57
61
let index = {
@@ -62,6 +66,9 @@ impl DefPathTable {
62
66
index
63
67
} ;
64
68
self . key_to_index . insert ( key, index) ;
69
+ self . def_path_hashes [ address_space. index ( ) ] . push ( def_path_hash) ;
70
+ debug_assert ! ( self . def_path_hashes[ address_space. index( ) ] . len( ) ==
71
+ self . index_to_key[ address_space. index( ) ] . len( ) ) ;
65
72
index
66
73
}
67
74
@@ -71,6 +78,12 @@ impl DefPathTable {
71
78
[ index. as_array_index ( ) ] . clone ( )
72
79
}
73
80
81
+ #[ inline( always) ]
82
+ pub fn def_path_hash ( & self , index : DefIndex ) -> u64 {
83
+ self . def_path_hashes [ index. address_space ( ) . index ( ) ]
84
+ [ index. as_array_index ( ) ]
85
+ }
86
+
74
87
#[ inline( always) ]
75
88
pub fn def_index_for_def_key ( & self , key : & DefKey ) -> Option < DefIndex > {
76
89
self . key_to_index . get ( key) . cloned ( )
@@ -116,17 +129,28 @@ impl DefPathTable {
116
129
117
130
impl Encodable for DefPathTable {
118
131
fn encode < S : Encoder > ( & self , s : & mut S ) -> Result < ( ) , S :: Error > {
132
+ // Index to key
119
133
self . index_to_key [ DefIndexAddressSpace :: Low . index ( ) ] . encode ( s) ?;
120
- self . index_to_key [ DefIndexAddressSpace :: High . index ( ) ] . encode ( s)
134
+ self . index_to_key [ DefIndexAddressSpace :: High . index ( ) ] . encode ( s) ?;
135
+
136
+ // DefPath hashes
137
+ self . def_path_hashes [ DefIndexAddressSpace :: Low . index ( ) ] . encode ( s) ?;
138
+ self . def_path_hashes [ DefIndexAddressSpace :: High . index ( ) ] . encode ( s) ?;
139
+
140
+ Ok ( ( ) )
121
141
}
122
142
}
123
143
124
144
impl Decodable for DefPathTable {
125
145
fn decode < D : Decoder > ( d : & mut D ) -> Result < DefPathTable , D :: Error > {
126
146
let index_to_key_lo: Vec < DefKey > = Decodable :: decode ( d) ?;
127
- let index_to_key_high : Vec < DefKey > = Decodable :: decode ( d) ?;
147
+ let index_to_key_hi : Vec < DefKey > = Decodable :: decode ( d) ?;
128
148
129
- let index_to_key = [ index_to_key_lo, index_to_key_high] ;
149
+ let def_path_hashes_lo: Vec < u64 > = Decodable :: decode ( d) ?;
150
+ let def_path_hashes_hi: Vec < u64 > = Decodable :: decode ( d) ?;
151
+
152
+ let index_to_key = [ index_to_key_lo, index_to_key_hi] ;
153
+ let def_path_hashes = [ def_path_hashes_lo, def_path_hashes_hi] ;
130
154
131
155
let mut key_to_index = FxHashMap ( ) ;
132
156
@@ -141,6 +165,7 @@ impl Decodable for DefPathTable {
141
165
Ok ( DefPathTable {
142
166
index_to_key : index_to_key,
143
167
key_to_index : key_to_index,
168
+ def_path_hashes : def_path_hashes,
144
169
} )
145
170
}
146
171
}
@@ -184,6 +209,29 @@ pub struct DefKey {
184
209
pub disambiguated_data : DisambiguatedDefPathData ,
185
210
}
186
211
212
+ impl DefKey {
213
+ fn compute_stable_hash ( & self , parent_hash : u64 ) -> u64 {
214
+ let mut hasher = StableHasher :: new ( ) ;
215
+
216
+ // We hash a 0u8 here to disambiguate between regular DefPath hashes,
217
+ // and the special "root_parent" below.
218
+ 0u8 . hash ( & mut hasher) ;
219
+ parent_hash. hash ( & mut hasher) ;
220
+ self . disambiguated_data . hash ( & mut hasher) ;
221
+ hasher. finish ( )
222
+ }
223
+
224
+ fn root_parent_stable_hash ( crate_name : & str , crate_disambiguator : & str ) -> u64 {
225
+ let mut hasher = StableHasher :: new ( ) ;
226
+ // Disambiguate this from a regular DefPath hash,
227
+ // see compute_stable_hash() above.
228
+ 1u8 . hash ( & mut hasher) ;
229
+ crate_name. hash ( & mut hasher) ;
230
+ crate_disambiguator. hash ( & mut hasher) ;
231
+ hasher. finish ( )
232
+ }
233
+ }
234
+
187
235
/// Pair of `DefPathData` and an integer disambiguator. The integer is
188
236
/// normally 0, but in the event that there are multiple defs with the
189
237
/// same `parent` and `data`, we use this field to disambiguate
@@ -271,19 +319,6 @@ impl DefPath {
271
319
272
320
s
273
321
}
274
-
275
- pub fn deterministic_hash ( & self , tcx : TyCtxt ) -> u64 {
276
- debug ! ( "deterministic_hash({:?})" , self ) ;
277
- let mut state = StableHasher :: new ( ) ;
278
- self . deterministic_hash_to ( tcx, & mut state) ;
279
- state. finish ( )
280
- }
281
-
282
- pub fn deterministic_hash_to < H : Hasher > ( & self , tcx : TyCtxt , state : & mut H ) {
283
- tcx. original_crate_name ( self . krate ) . as_str ( ) . hash ( state) ;
284
- tcx. crate_disambiguator ( self . krate ) . as_str ( ) . hash ( state) ;
285
- self . data . hash ( state) ;
286
- }
287
322
}
288
323
289
324
#[ derive( Clone , Debug , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
@@ -338,6 +373,7 @@ impl Definitions {
338
373
table : DefPathTable {
339
374
index_to_key : [ vec ! [ ] , vec ! [ ] ] ,
340
375
key_to_index : FxHashMap ( ) ,
376
+ def_path_hashes : [ vec ! [ ] , vec ! [ ] ] ,
341
377
} ,
342
378
node_to_def_index : NodeMap ( ) ,
343
379
def_index_to_node : [ vec ! [ ] , vec ! [ ] ] ,
@@ -359,6 +395,11 @@ impl Definitions {
359
395
self . table . def_key ( index)
360
396
}
361
397
398
+ #[ inline( always) ]
399
+ pub fn def_path_hash ( & self , index : DefIndex ) -> u64 {
400
+ self . table . def_path_hash ( index)
401
+ }
402
+
362
403
pub fn def_index_for_def_key ( & self , key : DefKey ) -> Option < DefIndex > {
363
404
self . table . def_index_for_def_key ( & key)
364
405
}
@@ -398,12 +439,38 @@ impl Definitions {
398
439
self . node_to_hir_id [ node_id]
399
440
}
400
441
442
+ /// Add a definition with a parent definition.
443
+ pub fn create_root_def ( & mut self ,
444
+ crate_name : & str ,
445
+ crate_disambiguator : & str )
446
+ -> DefIndex {
447
+ let key = DefKey {
448
+ parent : None ,
449
+ disambiguated_data : DisambiguatedDefPathData {
450
+ data : DefPathData :: CrateRoot ,
451
+ disambiguator : 0
452
+ }
453
+ } ;
454
+
455
+ let parent_hash = DefKey :: root_parent_stable_hash ( crate_name,
456
+ crate_disambiguator) ;
457
+ let def_path_hash = key. compute_stable_hash ( parent_hash) ;
458
+
459
+ // Create the definition.
460
+ let address_space = super :: ITEM_LIKE_SPACE ;
461
+ let index = self . table . allocate ( key, def_path_hash, address_space) ;
462
+ assert ! ( self . def_index_to_node[ address_space. index( ) ] . is_empty( ) ) ;
463
+ self . def_index_to_node [ address_space. index ( ) ] . push ( ast:: CRATE_NODE_ID ) ;
464
+ self . node_to_def_index . insert ( ast:: CRATE_NODE_ID , index) ;
465
+
466
+ index
467
+ }
468
+
401
469
/// Add a definition with a parent definition.
402
470
pub fn create_def_with_parent ( & mut self ,
403
- parent : Option < DefIndex > ,
471
+ parent : DefIndex ,
404
472
node_id : ast:: NodeId ,
405
473
data : DefPathData ,
406
- // is_owner: bool)
407
474
address_space : DefIndexAddressSpace )
408
475
-> DefIndex {
409
476
debug ! ( "create_def_with_parent(parent={:?}, node_id={:?}, data={:?})" ,
@@ -415,12 +482,13 @@ impl Definitions {
415
482
data,
416
483
self . table. def_key( self . node_to_def_index[ & node_id] ) ) ;
417
484
418
- assert_eq ! ( parent. is_some( ) , data != DefPathData :: CrateRoot ) ;
485
+ // The root node must be created with create_root_def()
486
+ assert ! ( data != DefPathData :: CrateRoot ) ;
419
487
420
488
// Find a unique DefKey. This basically means incrementing the disambiguator
421
489
// until we get no match.
422
490
let mut key = DefKey {
423
- parent : parent,
491
+ parent : Some ( parent) ,
424
492
disambiguated_data : DisambiguatedDefPathData {
425
493
data : data,
426
494
disambiguator : 0
@@ -431,10 +499,13 @@ impl Definitions {
431
499
key. disambiguated_data . disambiguator += 1 ;
432
500
}
433
501
502
+ let parent_hash = self . table . def_path_hash ( parent) ;
503
+ let def_path_hash = key. compute_stable_hash ( parent_hash) ;
504
+
434
505
debug ! ( "create_def_with_parent: after disambiguation, key = {:?}" , key) ;
435
506
436
507
// Create the definition.
437
- let index = self . table . allocate ( key, address_space) ;
508
+ let index = self . table . allocate ( key, def_path_hash , address_space) ;
438
509
assert_eq ! ( index. as_array_index( ) ,
439
510
self . def_index_to_node[ address_space. index( ) ] . len( ) ) ;
440
511
self . def_index_to_node [ address_space. index ( ) ] . push ( node_id) ;
0 commit comments