@@ -25,25 +25,33 @@ use rustc::hir::def::{Def, PathResolution};
25
25
use rustc:: hir:: def_id:: DefId ;
26
26
use rustc:: hir:: intravisit as visit;
27
27
use rustc:: hir:: intravisit:: { Visitor , FnKind } ;
28
- use rustc:: hir:: map:: DefPath ;
29
28
use rustc:: ty:: TyCtxt ;
29
+ use rustc:: util:: nodemap:: DefIdMap ;
30
30
31
31
use std:: hash:: { Hash , SipHasher } ;
32
32
33
33
pub struct StrictVersionHashVisitor < ' a , ' tcx : ' a > {
34
34
pub tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
35
35
pub st : & ' a mut SipHasher ,
36
+
37
+ // collect a deterministic hash of def-ids that we have seen
38
+ def_id_hashes : DefIdMap < u64 > ,
36
39
}
37
40
38
41
impl < ' a , ' tcx > StrictVersionHashVisitor < ' a , ' tcx > {
39
42
pub fn new ( st : & ' a mut SipHasher ,
40
43
tcx : TyCtxt < ' a , ' tcx , ' tcx > )
41
44
-> Self {
42
- StrictVersionHashVisitor { st : st, tcx : tcx }
45
+ StrictVersionHashVisitor { st : st, tcx : tcx, def_id_hashes : DefIdMap ( ) }
43
46
}
44
47
45
- fn hash_def_path ( & mut self , path : & DefPath ) {
46
- path. deterministic_hash_to ( self . tcx , self . st ) ;
48
+ fn compute_def_id_hash ( & mut self , def_id : DefId ) -> u64 {
49
+ let tcx = self . tcx ;
50
+ * self . def_id_hashes . entry ( def_id)
51
+ . or_insert_with ( || {
52
+ let def_path = tcx. def_path ( def_id) ;
53
+ def_path. deterministic_hash ( tcx)
54
+ } )
47
55
}
48
56
}
49
57
@@ -376,15 +384,22 @@ impl<'a, 'tcx> StrictVersionHashVisitor<'a, 'tcx> {
376
384
if let Some ( traits) = self . tcx . trait_map . get ( & id) {
377
385
debug ! ( "hash_resolve: id={:?} traits={:?} st={:?}" , id, traits, self . st) ;
378
386
traits. len ( ) . hash ( self . st ) ;
379
- for candidate in traits {
380
- self . hash_def_id ( candidate. def_id ) ;
381
- }
387
+
388
+ // The ordering of the candidates is not fixed. So we hash
389
+ // the def-ids and then sort them and hash the collection.
390
+ let mut candidates: Vec < _ > =
391
+ traits. iter ( )
392
+ . map ( |& TraitCandidate { def_id, import_id : _ } | {
393
+ self . compute_def_id_hash ( def_id)
394
+ } )
395
+ . collect ( ) ;
396
+ candidates. sort ( ) ;
397
+ candidates. hash ( self . st ) ;
382
398
}
383
399
}
384
400
385
401
fn hash_def_id ( & mut self , def_id : DefId ) {
386
- let def_path = self . tcx . def_path ( def_id) ;
387
- self . hash_def_path ( & def_path) ;
402
+ self . compute_def_id_hash ( def_id) . hash ( self . st ) ;
388
403
}
389
404
390
405
fn hash_partial_def ( & mut self , def : & PathResolution ) {
0 commit comments