@@ -19,12 +19,14 @@ use self::SawAbiComponent::*;
19
19
use syntax:: ast:: { self , Name , NodeId } ;
20
20
use syntax:: parse:: token;
21
21
use syntax_pos:: Span ;
22
- use rustc:: ty:: TyCtxt ;
23
22
use rustc:: hir;
24
23
use rustc:: hir:: * ;
25
- use rustc:: hir:: map:: DefPath ;
24
+ use rustc:: hir:: def:: { Def , PathResolution } ;
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
+ use rustc:: ty:: TyCtxt ;
28
30
29
31
use std:: hash:: { Hash , SipHasher } ;
30
32
@@ -343,4 +345,95 @@ impl<'a, 'tcx> Visitor<'a> for StrictVersionHashVisitor<'a, 'tcx> {
343
345
debug ! ( "visit_arm: st={:?}" , self . st) ;
344
346
SawArm . hash ( self . st ) ; visit:: walk_arm ( self , a)
345
347
}
348
+
349
+ fn visit_id ( & mut self , id : NodeId ) {
350
+ debug ! ( "visit_id: id={} st={:?}" , id, self . st) ;
351
+ self . hash_resolve ( id) ;
352
+ }
353
+ }
354
+
355
+ #[ derive( Hash ) ]
356
+ pub enum DefHash {
357
+ SawDefId ,
358
+ SawLabel ,
359
+ SawPrimTy ,
360
+ SawSelfTy ,
361
+ SawErr ,
362
+ }
363
+
364
+ impl < ' a , ' tcx > StrictVersionHashVisitor < ' a , ' tcx > {
365
+ fn hash_resolve ( & mut self , id : ast:: NodeId ) {
366
+ // Because whether or not a given id has an entry is dependent
367
+ // solely on expr variant etc, we don't need to hash whether
368
+ // or not an entry was present (we are already hashing what
369
+ // variant it is above when we visit the HIR).
370
+
371
+ if let Some ( def) = self . tcx . def_map . borrow ( ) . get ( & id) {
372
+ self . hash_partial_def ( def) ;
373
+ }
374
+
375
+ if let Some ( traits) = self . tcx . trait_map . get ( & id) {
376
+ traits. len ( ) . hash ( self . st ) ;
377
+ for candidate in traits {
378
+ self . hash_def_id ( candidate. def_id ) ;
379
+ }
380
+ }
381
+ }
382
+
383
+ fn hash_def_id ( & mut self , def_id : DefId ) {
384
+ let def_path = self . tcx . def_path ( def_id) ;
385
+ self . hash_def_path ( & def_path) ;
386
+ }
387
+
388
+ fn hash_partial_def ( & mut self , def : & PathResolution ) {
389
+ self . hash_def ( def. base_def ) ;
390
+ def. depth . hash ( self . st ) ;
391
+ }
392
+
393
+ fn hash_def ( & mut self , def : Def ) {
394
+ match def {
395
+ // Crucial point: for all of these variants, the variant +
396
+ // add'l data that is added is always the same if the
397
+ // def-id is the same, so it suffices to hash the def-id
398
+ Def :: Fn ( ..) |
399
+ Def :: Mod ( ..) |
400
+ Def :: ForeignMod ( ..) |
401
+ Def :: Static ( ..) |
402
+ Def :: Variant ( ..) |
403
+ Def :: Enum ( ..) |
404
+ Def :: TyAlias ( ..) |
405
+ Def :: AssociatedTy ( ..) |
406
+ Def :: TyParam ( ..) |
407
+ Def :: Struct ( ..) |
408
+ Def :: Trait ( ..) |
409
+ Def :: Method ( ..) |
410
+ Def :: Const ( ..) |
411
+ Def :: AssociatedConst ( ..) |
412
+ Def :: Local ( ..) |
413
+ Def :: Upvar ( ..) => {
414
+ DefHash :: SawDefId . hash ( self . st ) ;
415
+ self . hash_def_id ( def. def_id ( ) ) ;
416
+ }
417
+
418
+ Def :: Label ( ..) => {
419
+ DefHash :: SawLabel . hash ( self . st ) ;
420
+ // we don't encode the `id` because it always refers to something
421
+ // within this item, so if it changed, there would have to be other
422
+ // changes too
423
+ }
424
+ Def :: PrimTy ( ref prim_ty) => {
425
+ DefHash :: SawPrimTy . hash ( self . st ) ;
426
+ prim_ty. hash ( self . st ) ;
427
+ }
428
+ Def :: SelfTy ( ..) => {
429
+ DefHash :: SawSelfTy . hash ( self . st ) ;
430
+ // the meaning of Self is always the same within a
431
+ // given context, so we don't need to hash the other
432
+ // fields
433
+ }
434
+ Def :: Err => {
435
+ DefHash :: SawErr . hash ( self . st ) ;
436
+ }
437
+ }
438
+ }
346
439
}
0 commit comments