12
12
13
13
use hir:: def_id:: DefId ;
14
14
use infer:: InferCtxt ;
15
+ use hir:: map as ast_map;
15
16
use hir:: pat_util;
16
17
use traits:: { self , Reveal } ;
17
18
use ty:: { self , Ty , AdtKind , TyCtxt , TypeAndMut , TypeFlags , TypeFoldable } ;
@@ -388,16 +389,77 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
388
389
}
389
390
}
390
391
392
+ // When hashing a type this ends up affecting properties like symbol names. We
393
+ // want these symbol names to be calculated independent of other factors like
394
+ // what architecture you're compiling *from*.
395
+ //
396
+ // The hashing just uses the standard `Hash` trait, but the implementations of
397
+ // `Hash` for the `usize` and `isize` types are *not* architecture independent
398
+ // (e.g. they has 4 or 8 bytes). As a result we want to avoid `usize` and
399
+ // `isize` completely when hashing. To ensure that these don't leak in we use a
400
+ // custom hasher implementation here which inflates the size of these to a `u64`
401
+ // and `i64`.
402
+ struct WidenUsizeHasher < H > {
403
+ inner : H ,
404
+ }
405
+
406
+ impl < H > WidenUsizeHasher < H > {
407
+ fn new ( inner : H ) -> WidenUsizeHasher < H > {
408
+ WidenUsizeHasher { inner : inner }
409
+ }
410
+ }
411
+
412
+ impl < H : Hasher > Hasher for WidenUsizeHasher < H > {
413
+ fn write ( & mut self , bytes : & [ u8 ] ) {
414
+ self . inner . write ( bytes)
415
+ }
416
+
417
+ fn finish ( & self ) -> u64 {
418
+ self . inner . finish ( )
419
+ }
420
+
421
+ fn write_u8 ( & mut self , i : u8 ) {
422
+ self . inner . write_u8 ( i)
423
+ }
424
+ fn write_u16 ( & mut self , i : u16 ) {
425
+ self . inner . write_u16 ( i)
426
+ }
427
+ fn write_u32 ( & mut self , i : u32 ) {
428
+ self . inner . write_u32 ( i)
429
+ }
430
+ fn write_u64 ( & mut self , i : u64 ) {
431
+ self . inner . write_u64 ( i)
432
+ }
433
+ fn write_usize ( & mut self , i : usize ) {
434
+ self . inner . write_u64 ( i as u64 )
435
+ }
436
+ fn write_i8 ( & mut self , i : i8 ) {
437
+ self . inner . write_i8 ( i)
438
+ }
439
+ fn write_i16 ( & mut self , i : i16 ) {
440
+ self . inner . write_i16 ( i)
441
+ }
442
+ fn write_i32 ( & mut self , i : i32 ) {
443
+ self . inner . write_i32 ( i)
444
+ }
445
+ fn write_i64 ( & mut self , i : i64 ) {
446
+ self . inner . write_i64 ( i)
447
+ }
448
+ fn write_isize ( & mut self , i : isize ) {
449
+ self . inner . write_i64 ( i as i64 )
450
+ }
451
+ }
452
+
391
453
pub struct TypeIdHasher < ' a , ' gcx : ' a +' tcx , ' tcx : ' a , H > {
392
454
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
393
- state : H
455
+ state : WidenUsizeHasher < H > ,
394
456
}
395
457
396
458
impl < ' a , ' gcx , ' tcx , H : Hasher > TypeIdHasher < ' a , ' gcx , ' tcx , H > {
397
459
pub fn new ( tcx : TyCtxt < ' a , ' gcx , ' tcx > , state : H ) -> Self {
398
460
TypeIdHasher {
399
461
tcx : tcx,
400
- state : state
462
+ state : WidenUsizeHasher :: new ( state) ,
401
463
}
402
464
}
403
465
@@ -421,9 +483,12 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeIdHasher<'a, 'gcx, 'tcx, H> {
421
483
fn def_id ( & mut self , did : DefId ) {
422
484
// Hash the DefPath corresponding to the DefId, which is independent
423
485
// of compiler internal state.
424
- let tcx = self . tcx ;
425
- let def_path = tcx. def_path ( did) ;
426
- def_path. deterministic_hash_to ( tcx, & mut self . state ) ;
486
+ let path = self . tcx . def_path ( did) ;
487
+ self . def_path ( & path)
488
+ }
489
+
490
+ pub fn def_path ( & mut self , def_path : & ast_map:: DefPath ) {
491
+ def_path. deterministic_hash_to ( self . tcx , & mut self . state ) ;
427
492
}
428
493
}
429
494
@@ -436,7 +501,7 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
436
501
TyInt ( i) => self . hash ( i) ,
437
502
TyUint ( u) => self . hash ( u) ,
438
503
TyFloat ( f) => self . hash ( f) ,
439
- TyArray ( _, n) => self . hash ( n as u64 ) ,
504
+ TyArray ( _, n) => self . hash ( n) ,
440
505
TyRawPtr ( m) |
441
506
TyRef ( _, m) => self . hash ( m. mutbl ) ,
442
507
TyClosure ( def_id, _) |
@@ -447,14 +512,14 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
447
512
self . hash ( f. unsafety ) ;
448
513
self . hash ( f. abi ) ;
449
514
self . hash ( f. sig . variadic ( ) ) ;
450
- self . hash ( f. sig . inputs ( ) . skip_binder ( ) . len ( ) as u64 ) ;
515
+ self . hash ( f. sig . inputs ( ) . skip_binder ( ) . len ( ) ) ;
451
516
}
452
517
TyTrait ( ref data) => {
453
518
self . def_id ( data. principal . def_id ( ) ) ;
454
519
self . hash ( data. builtin_bounds ) ;
455
520
}
456
521
TyTuple ( tys) => {
457
- self . hash ( tys. len ( ) as u64 ) ;
522
+ self . hash ( tys. len ( ) ) ;
458
523
}
459
524
TyParam ( p) => {
460
525
self . hash ( p. idx ) ;
0 commit comments