@@ -21,7 +21,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
2121use rustc_data_structures:: stable_hasher:: StableHasher ;
2222use serialize:: { Encodable , Decodable , Encoder , Decoder } ;
2323use std:: fmt:: Write ;
24- use std:: hash:: { Hash , Hasher } ;
24+ use std:: hash:: Hash ;
2525use syntax:: ast;
2626use syntax:: symbol:: { Symbol , InternedString } ;
2727use ty:: TyCtxt ;
@@ -34,6 +34,7 @@ use util::nodemap::NodeMap;
3434pub struct DefPathTable {
3535 index_to_key : [ Vec < DefKey > ; 2 ] ,
3636 key_to_index : FxHashMap < DefKey , DefIndex > ,
37+ def_path_hashes : [ Vec < u64 > ; 2 ] ,
3738}
3839
3940// Unfortunately we have to provide a manual impl of Clone because of the
@@ -44,6 +45,8 @@ impl Clone for DefPathTable {
4445 index_to_key : [ self . index_to_key [ 0 ] . clone ( ) ,
4546 self . index_to_key [ 1 ] . clone ( ) ] ,
4647 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 ( ) ] ,
4750 }
4851 }
4952}
@@ -52,6 +55,7 @@ impl DefPathTable {
5255
5356 fn allocate ( & mut self ,
5457 key : DefKey ,
58+ def_path_hash : u64 ,
5559 address_space : DefIndexAddressSpace )
5660 -> DefIndex {
5761 let index = {
@@ -62,6 +66,9 @@ impl DefPathTable {
6266 index
6367 } ;
6468 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( ) ) ;
6572 index
6673 }
6774
@@ -71,6 +78,12 @@ impl DefPathTable {
7178 [ index. as_array_index ( ) ] . clone ( )
7279 }
7380
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+
7487 #[ inline( always) ]
7588 pub fn def_index_for_def_key ( & self , key : & DefKey ) -> Option < DefIndex > {
7689 self . key_to_index . get ( key) . cloned ( )
@@ -116,17 +129,28 @@ impl DefPathTable {
116129
117130impl Encodable for DefPathTable {
118131 fn encode < S : Encoder > ( & self , s : & mut S ) -> Result < ( ) , S :: Error > {
132+ // Index to key
119133 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 ( ( ) )
121141 }
122142}
123143
124144impl Decodable for DefPathTable {
125145 fn decode < D : Decoder > ( d : & mut D ) -> Result < DefPathTable , D :: Error > {
126146 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) ?;
128148
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] ;
130154
131155 let mut key_to_index = FxHashMap ( ) ;
132156
@@ -141,6 +165,7 @@ impl Decodable for DefPathTable {
141165 Ok ( DefPathTable {
142166 index_to_key : index_to_key,
143167 key_to_index : key_to_index,
168+ def_path_hashes : def_path_hashes,
144169 } )
145170 }
146171}
@@ -184,6 +209,29 @@ pub struct DefKey {
184209 pub disambiguated_data : DisambiguatedDefPathData ,
185210}
186211
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+
187235/// Pair of `DefPathData` and an integer disambiguator. The integer is
188236/// normally 0, but in the event that there are multiple defs with the
189237/// same `parent` and `data`, we use this field to disambiguate
@@ -271,19 +319,6 @@ impl DefPath {
271319
272320 s
273321 }
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- }
287322}
288323
289324#[ derive( Clone , Debug , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
@@ -338,6 +373,7 @@ impl Definitions {
338373 table : DefPathTable {
339374 index_to_key : [ vec ! [ ] , vec ! [ ] ] ,
340375 key_to_index : FxHashMap ( ) ,
376+ def_path_hashes : [ vec ! [ ] , vec ! [ ] ] ,
341377 } ,
342378 node_to_def_index : NodeMap ( ) ,
343379 def_index_to_node : [ vec ! [ ] , vec ! [ ] ] ,
@@ -359,6 +395,11 @@ impl Definitions {
359395 self . table . def_key ( index)
360396 }
361397
398+ #[ inline( always) ]
399+ pub fn def_path_hash ( & self , index : DefIndex ) -> u64 {
400+ self . table . def_path_hash ( index)
401+ }
402+
362403 pub fn def_index_for_def_key ( & self , key : DefKey ) -> Option < DefIndex > {
363404 self . table . def_index_for_def_key ( & key)
364405 }
@@ -398,12 +439,38 @@ impl Definitions {
398439 self . node_to_hir_id [ node_id]
399440 }
400441
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+
401469 /// Add a definition with a parent definition.
402470 pub fn create_def_with_parent ( & mut self ,
403- parent : Option < DefIndex > ,
471+ parent : DefIndex ,
404472 node_id : ast:: NodeId ,
405473 data : DefPathData ,
406- // is_owner: bool)
407474 address_space : DefIndexAddressSpace )
408475 -> DefIndex {
409476 debug ! ( "create_def_with_parent(parent={:?}, node_id={:?}, data={:?})" ,
@@ -415,12 +482,13 @@ impl Definitions {
415482 data,
416483 self . table. def_key( self . node_to_def_index[ & node_id] ) ) ;
417484
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 ) ;
419487
420488 // Find a unique DefKey. This basically means incrementing the disambiguator
421489 // until we get no match.
422490 let mut key = DefKey {
423- parent : parent,
491+ parent : Some ( parent) ,
424492 disambiguated_data : DisambiguatedDefPathData {
425493 data : data,
426494 disambiguator : 0
@@ -431,10 +499,13 @@ impl Definitions {
431499 key. disambiguated_data . disambiguator += 1 ;
432500 }
433501
502+ let parent_hash = self . table . def_path_hash ( parent) ;
503+ let def_path_hash = key. compute_stable_hash ( parent_hash) ;
504+
434505 debug ! ( "create_def_with_parent: after disambiguation, key = {:?}" , key) ;
435506
436507 // Create the definition.
437- let index = self . table . allocate ( key, address_space) ;
508+ let index = self . table . allocate ( key, def_path_hash , address_space) ;
438509 assert_eq ! ( index. as_array_index( ) ,
439510 self . def_index_to_node[ address_space. index( ) ] . len( ) ) ;
440511 self . def_index_to_node [ address_space. index ( ) ] . push ( node_id) ;
0 commit comments