Skip to content

Commit ad5cbd7

Browse files
committed
Change type id to contain a pointer to the unique type id information
1 parent bac41e4 commit ad5cbd7

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

library/core/src/any.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -708,9 +708,15 @@ impl dyn Any + Send + Sync {
708708
#[derive(Clone, Copy, Eq, PartialOrd, Ord)]
709709
#[stable(feature = "rust1", since = "1.0.0")]
710710
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],
714720
#[cfg(feature = "debug_typeid")]
715721
name: &'static str,
716722
}
@@ -719,7 +725,16 @@ pub struct TypeId {
719725
impl 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,7 @@ 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+
self.data.full_hash[..8].hash(state);
778795
}
779796
}
780797

0 commit comments

Comments
 (0)