@@ -708,9 +708,15 @@ impl dyn Any + Send + Sync {
708
708
#[ derive( Clone , Copy , Eq , PartialOrd , Ord ) ]
709
709
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
710
710
pub struct TypeId {
711
- // We avoid using `u128` because that imposes higher alignment requirements on many platforms.
712
- // See issue #115620 for more information.
713
- t : ( u64 , u64 ) ,
711
+ /// Quick accept: if pointers are the same, the ids are the same
712
+ data : & ' static TypeIdData ,
713
+ /// Quick reject: if hashes are different, the ids are different
714
+ partial_hash : usize ,
715
+ }
716
+
717
+ #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
718
+ struct TypeIdData {
719
+ full_hash : [ u8 ; 16 ] ,
714
720
#[ cfg( feature = "debug_typeid" ) ]
715
721
name : & ' static str ,
716
722
}
@@ -719,7 +725,16 @@ pub struct TypeId {
719
725
impl PartialEq for TypeId {
720
726
#[ inline]
721
727
fn eq ( & self , other : & Self ) -> bool {
722
- self . t == other. t
728
+ self . data as * const TypeIdData == other. data as * const TypeIdData
729
+ || ( self . partial_hash == other. partial_hash
730
+ && self . data . full_hash == other. data . full_hash )
731
+ }
732
+
733
+ #[ inline]
734
+ fn ne ( & self , other : & Self ) -> bool {
735
+ self . partial_hash != other. partial_hash
736
+ || ( self . data as * const TypeIdData != other. data as * const TypeIdData
737
+ && self . data . full_hash != other. data . full_hash )
723
738
}
724
739
}
725
740
@@ -742,19 +757,21 @@ impl TypeId {
742
757
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
743
758
#[ rustc_const_unstable( feature = "const_type_id" , issue = "77125" ) ]
744
759
pub const fn of < T : ?Sized + ' static > ( ) -> TypeId {
745
- let t: u128 = intrinsics:: type_id :: < T > ( ) ;
746
- let t1 = ( t >> 64 ) as u64 ;
747
- let t2 = t as u64 ;
748
-
749
- TypeId {
750
- t : ( t1, t2) ,
751
- #[ cfg( feature = "debug_typeid" ) ]
752
- name : type_name :: < T > ( ) ,
753
- }
760
+ let data = & const {
761
+ let t: u128 = intrinsics:: type_id :: < T > ( ) ;
762
+ TypeIdData {
763
+ full_hash : t. to_ne_bytes ( ) ,
764
+
765
+ #[ cfg( feature = "debug_typeid" ) ]
766
+ name : type_name :: < T > ( ) ,
767
+ }
768
+ } ;
769
+
770
+ TypeId { data, partial_hash : intrinsics:: type_id :: < T > ( ) as usize }
754
771
}
755
772
756
773
fn as_u128 ( self ) -> u128 {
757
- u128:: from ( self . t . 0 ) << 64 | u128 :: from ( self . t . 1 )
774
+ u128:: from_ne_bytes ( self . data . full_hash )
758
775
}
759
776
}
760
777
@@ -774,7 +791,7 @@ impl hash::Hash for TypeId {
774
791
// - It is correct to do so -- only hashing a subset of `self` is still
775
792
// compatible with an `Eq` implementation that considers the entire
776
793
// value, as ours does.
777
- self . t . 1 . hash ( state) ;
794
+ self . data . full_hash [ .. 8 ] . hash ( state) ;
778
795
}
779
796
}
780
797
0 commit comments