@@ -708,9 +708,15 @@ impl dyn Any + Send + Sync {
708708#[ derive( Clone , Copy , Eq , PartialOrd , Ord ) ]
709709#[ stable( feature = "rust1" , since = "1.0.0" ) ]
710710pub 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 ] ,
714720 #[ cfg( feature = "debug_typeid" ) ]
715721 name : & ' static str ,
716722}
@@ -719,7 +725,16 @@ pub struct TypeId {
719725impl PartialEq for TypeId {
720726 #[ inline]
721727 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 )
723738 }
724739}
725740
@@ -742,19 +757,21 @@ impl TypeId {
742757 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
743758 #[ rustc_const_unstable( feature = "const_type_id" , issue = "77125" ) ]
744759 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 }
754771 }
755772
756773 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 )
758775 }
759776}
760777
@@ -774,7 +791,12 @@ impl hash::Hash for TypeId {
774791 // - It is correct to do so -- only hashing a subset of `self` is still
775792 // compatible with an `Eq` implementation that considers the entire
776793 // value, as ours does.
777- self . t . 1 . hash ( state) ;
794+ if cfg ! ( target_pointer_width = "64" ) {
795+ self . partial_hash . hash ( state) ;
796+ } else {
797+ let [ _, _, _, _, _, _, _, _, data @ ..] = self . data . full_hash ;
798+ u64:: from_ne_bytes ( data) . hash ( state) ;
799+ }
778800 }
779801}
780802
0 commit comments