about summary refs log tree commit diff
path: root/library/core
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-06-08 12:36:17 +0200
committerGitHub <noreply@github.com>2023-06-08 12:36:17 +0200
commit8747c0ebea5dd04311cb56310a5b2f0d32258d2f (patch)
tree4a299e2fca2543eb767492033e28a8cb9183da95 /library/core
parenta0df04c0f2b9c0415c53e3cee8c4f9fa394a37b2 (diff)
parentb512004a4a04f80c650cde6b2239cd41c5509fc6 (diff)
downloadrust-8747c0ebea5dd04311cb56310a5b2f0d32258d2f.tar.gz
rust-8747c0ebea5dd04311cb56310a5b2f0d32258d2f.zip
Rollup merge of #109953 - thomcc:thomcc/typeid128, r=WaffleLapkin
Use 128 bits for TypeId hash

Preliminary/Draft impl of https://github.com/rust-lang/compiler-team/issues/608

Prior art (probably incomplete list)
- https://github.com/rust-lang/rust/pull/75923
- https://github.com/rust-lang/rust/pull/95845
Diffstat (limited to 'library/core')
-rw-r--r--library/core/src/any.rs31
-rw-r--r--library/core/src/intrinsics.rs17
2 files changed, 45 insertions, 3 deletions
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index 7969f4055dd..09f52d692d0 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -153,6 +153,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::fmt;
+use crate::hash;
 use crate::intrinsics;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -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")]
@@ -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);
     }
 }
 
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 6dca1fe1e69..9b8612485ac 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -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.
     ///