Skip to content

Commit 5a64f27

Browse files
authored
Rollup merge of #109953 - thomcc:thomcc/typeid128, r=WaffleLapkin
Use 128 bits for TypeId hash Preliminary/Draft impl of rust-lang/compiler-team#608 Prior art (probably incomplete list) - rust-lang/rust#75923 - rust-lang/rust#95845
2 parents 2423e10 + 3099f89 commit 5a64f27

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

core/src/any.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@
153153
#![stable(feature = "rust1", since = "1.0.0")]
154154

155155
use crate::fmt;
156+
use crate::hash;
156157
use crate::intrinsics;
157158

158159
///////////////////////////////////////////////////////////////////////////////
@@ -662,10 +663,10 @@ impl dyn Any + Send + Sync {
662663
/// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth
663664
/// noting that the hashes and ordering will vary between Rust releases. Beware
664665
/// of relying on them inside of your code!
665-
#[derive(Clone, Copy, Debug, Hash, Eq, PartialOrd, Ord)]
666+
#[derive(Clone, Copy, Debug, Eq, PartialOrd, Ord)]
666667
#[stable(feature = "rust1", since = "1.0.0")]
667668
pub struct TypeId {
668-
t: u64,
669+
t: u128,
669670
}
670671

671672
#[stable(feature = "rust1", since = "1.0.0")]
@@ -696,7 +697,31 @@ impl TypeId {
696697
#[stable(feature = "rust1", since = "1.0.0")]
697698
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
698699
pub const fn of<T: ?Sized + 'static>() -> TypeId {
699-
TypeId { t: intrinsics::type_id::<T>() }
700+
#[cfg(bootstrap)]
701+
let t = intrinsics::type_id::<T>() as u128;
702+
#[cfg(not(bootstrap))]
703+
let t: u128 = intrinsics::type_id::<T>();
704+
TypeId { t }
705+
}
706+
}
707+
708+
#[stable(feature = "rust1", since = "1.0.0")]
709+
impl hash::Hash for TypeId {
710+
#[inline]
711+
fn hash<H: hash::Hasher>(&self, state: &mut H) {
712+
// We only hash the lower 64 bits of our (128 bit) internal numeric ID,
713+
// because:
714+
// - The hashing algorithm which backs `TypeId` is expected to be
715+
// unbiased and high quality, meaning further mixing would be somewhat
716+
// redundant compared to choosing (the lower) 64 bits arbitrarily.
717+
// - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd
718+
// get from hashing the full value would probably not be useful
719+
// (especially given the previous point about the lower 64 bits being
720+
// high quality on their own).
721+
// - It is correct to do so -- only hashing a subset of `self` is still
722+
// with an `Eq` implementation that considers the entire value, as
723+
// ours does.
724+
(self.t as u64).hash(state);
700725
}
701726
}
702727

core/src/intrinsics.rs

+17
Original file line numberDiff line numberDiff line change
@@ -1057,8 +1057,25 @@ extern "rust-intrinsic" {
10571057
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
10581058
#[rustc_safe_intrinsic]
10591059
#[rustc_nounwind]
1060+
#[cfg(bootstrap)]
10601061
pub fn type_id<T: ?Sized + 'static>() -> u64;
10611062

1063+
/// Gets an identifier which is globally unique to the specified type. This
1064+
/// function will return the same value for a type regardless of whichever
1065+
/// crate it is invoked in.
1066+
///
1067+
/// Note that, unlike most intrinsics, this is safe to call;
1068+
/// it does not require an `unsafe` block.
1069+
/// Therefore, implementations must not require the user to uphold
1070+
/// any safety invariants.
1071+
///
1072+
/// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
1073+
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
1074+
#[rustc_safe_intrinsic]
1075+
#[rustc_nounwind]
1076+
#[cfg(not(bootstrap))]
1077+
pub fn type_id<T: ?Sized + 'static>() -> u128;
1078+
10621079
/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
10631080
/// This will statically either panic, or do nothing.
10641081
///

0 commit comments

Comments
 (0)