Skip to content

Commit

Permalink
Rollup merge of #109953 - thomcc:thomcc/typeid128, r=WaffleLapkin
Browse files Browse the repository at this point in the history
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
  • Loading branch information
matthiaskrgr authored Jun 8, 2023
2 parents 2423e10 + 3099f89 commit 5a64f27
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
31 changes: 28 additions & 3 deletions core/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use crate::fmt;
use crate::hash;
use crate::intrinsics;

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

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -696,7 +697,31 @@ impl TypeId {
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
pub const fn of<T: ?Sized + 'static>() -> TypeId {
TypeId { t: intrinsics::type_id::<T>() }
#[cfg(bootstrap)]
let t = intrinsics::type_id::<T>() as u128;
#[cfg(not(bootstrap))]
let t: u128 = intrinsics::type_id::<T>();
TypeId { t }
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl hash::Hash for TypeId {
#[inline]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
// We only hash the lower 64 bits of our (128 bit) internal numeric ID,
// because:
// - The hashing algorithm which backs `TypeId` is expected to be
// unbiased and high quality, meaning further mixing would be somewhat
// redundant compared to choosing (the lower) 64 bits arbitrarily.
// - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd
// get from hashing the full value would probably not be useful
// (especially given the previous point about the lower 64 bits being
// high quality on their own).
// - It is correct to do so -- only hashing a subset of `self` is still
// with an `Eq` implementation that considers the entire value, as
// ours does.
(self.t as u64).hash(state);
}
}

Expand Down
17 changes: 17 additions & 0 deletions core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1057,8 +1057,25 @@ extern "rust-intrinsic" {
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
#[rustc_safe_intrinsic]
#[rustc_nounwind]
#[cfg(bootstrap)]
pub fn type_id<T: ?Sized + 'static>() -> u64;

/// Gets an identifier which is globally unique to the specified type. This
/// function will return the same value for a type regardless of whichever
/// crate it is invoked in.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
///
/// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
#[rustc_safe_intrinsic]
#[rustc_nounwind]
#[cfg(not(bootstrap))]
pub fn type_id<T: ?Sized + 'static>() -> u128;

/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
/// This will statically either panic, or do nothing.
///
Expand Down

0 comments on commit 5a64f27

Please sign in to comment.