@@ -19,12 +19,14 @@ use self::SawAbiComponent::*;
1919use syntax:: ast:: { self , Name , NodeId } ;
2020use syntax:: parse:: token;
2121use syntax_pos:: Span ;
22- use rustc:: ty:: TyCtxt ;
2322use rustc:: hir;
2423use rustc:: hir:: * ;
25- use rustc:: hir:: map:: DefPath ;
24+ use rustc:: hir:: def:: { Def , PathResolution } ;
25+ use rustc:: hir:: def_id:: DefId ;
2626use rustc:: hir:: intravisit as visit;
2727use rustc:: hir:: intravisit:: { Visitor , FnKind } ;
28+ use rustc:: hir:: map:: DefPath ;
29+ use rustc:: ty:: TyCtxt ;
2830
2931use std:: hash:: { Hash , SipHasher } ;
3032
@@ -343,4 +345,95 @@ impl<'a, 'tcx> Visitor<'a> for StrictVersionHashVisitor<'a, 'tcx> {
343345 debug ! ( "visit_arm: st={:?}" , self . st) ;
344346 SawArm . hash ( self . st ) ; visit:: walk_arm ( self , a)
345347 }
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+ }
346439}
0 commit comments