diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index ca7c0772de86e..ed636b80fc59f 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -960,7 +960,13 @@ mod impls { fn hash(&self, state: &mut H) { let (address, metadata) = self.to_raw_parts(); state.write_usize(address.addr()); - metadata.hash(state); + if mem::size_of_val(&metadata) == mem::size_of::() { + // SAFETY: This is either `usize` or `DynMetadata`. In both case doing transmute + // is okay. + // We can't hash `DynMetadata` directly so transmute it to usize before hashing. + let metadata_as_usize = unsafe { mem::transmute_copy(&metadata) }; + state.write_usize(metadata_as_usize); + } } } @@ -968,9 +974,7 @@ mod impls { impl Hash for *mut T { #[inline] fn hash(&self, state: &mut H) { - let (address, metadata) = self.to_raw_parts(); - state.write_usize(address.addr()); - metadata.hash(state); + self.cast_const().hash(state); } } } diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 2ea032d4affe0..35ebdd103618f 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -1,7 +1,6 @@ #![unstable(feature = "ptr_metadata", issue = "81513")] use crate::fmt; -use crate::hash::{Hash, Hasher}; /// Provides the pointer metadata type of any pointed-to type. /// @@ -57,7 +56,7 @@ pub trait Pointee { // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata` // in `library/core/src/ptr/metadata.rs` // in sync with those here: - type Metadata: Copy + Send + Sync + Ord + Hash + Unpin; + type Metadata: Copy + Send + Sync + Unpin; } /// Pointers to types implementing this trait alias are “thin”. @@ -241,33 +240,3 @@ impl Clone for DynMetadata { *self } } - -impl Eq for DynMetadata {} - -impl PartialEq for DynMetadata { - #[inline] - fn eq(&self, other: &Self) -> bool { - crate::ptr::eq::(self.vtable_ptr, other.vtable_ptr) - } -} - -impl Ord for DynMetadata { - #[inline] - fn cmp(&self, other: &Self) -> crate::cmp::Ordering { - (self.vtable_ptr as *const VTable).cmp(&(other.vtable_ptr as *const VTable)) - } -} - -impl PartialOrd for DynMetadata { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Hash for DynMetadata { - #[inline] - fn hash(&self, hasher: &mut H) { - crate::ptr::hash::(self.vtable_ptr, hasher) - } -} diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index c02cd99cc4477..8375ae951bae7 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -801,17 +801,17 @@ fn ptr_metadata() { #[test] fn ptr_metadata_bounds() { - fn metadata_eq_method_address() -> usize { - // The `Metadata` associated type has an `Ord` bound, so this is valid: - <::Metadata as PartialEq>::eq as usize + fn metadata_clone_method_address() -> usize { + // The `Metadata` associated type has an `Copy` bound, so this is valid: + <::Metadata as Clone>::clone as usize } // "Synthetic" trait impls generated by the compiler like those of `Pointee` // are not checked for bounds of associated type. // So with a buggy core we could have both: // * `::Metadata == DynMetadata` - // * `DynMetadata: !PartialEq` + // * `DynMetadata: !Clone` // … and cause an ICE here: - metadata_eq_method_address::(); + metadata_clone_method_address::(); // For this reason, let’s check here that bounds are satisfied: @@ -825,7 +825,7 @@ fn ptr_metadata_bounds() { fn static_assert_expected_bounds_for_metadata() where // Keep this in sync with the associated type in `library/core/src/ptr/metadata.rs` - Meta: Copy + Send + Sync + Ord + std::hash::Hash + Unpin, + Meta: Copy + Send + Sync + Unpin, { } }