diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index f3a47cba759e6..4ac28b8308e73 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2411,18 +2411,13 @@ impl Clone for Vec { /// as required by the `core::borrow::Borrow` implementation. /// /// ``` -/// use std::hash::{BuildHasher, Hash, Hasher}; -/// -/// fn hash_of(x: impl Hash, b: &impl BuildHasher) -> u64 { -/// let mut h = b.build_hasher(); -/// x.hash(&mut h); -/// h.finish() -/// } +/// #![feature(build_hasher_simple_hash_one)] +/// use std::hash::BuildHasher; /// /// let b = std::collections::hash_map::RandomState::new(); /// let v: Vec = vec![0xa8, 0x3c, 0x09]; /// let s: &[u8] = &[0xa8, 0x3c, 0x09]; -/// assert_eq!(hash_of(v, &b), hash_of(s, &b)); +/// assert_eq!(b.hash_one(v), b.hash_one(s)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] impl Hash for Vec { diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index f44e22b3dbd7c..030b42a53d05d 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -143,18 +143,13 @@ impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] { /// as required by the `Borrow` implementation. /// /// ``` -/// use std::hash::{BuildHasher, Hash, Hasher}; -/// -/// fn hash_of(x: impl Hash, b: &impl BuildHasher) -> u64 { -/// let mut h = b.build_hasher(); -/// x.hash(&mut h); -/// h.finish() -/// } +/// #![feature(build_hasher_simple_hash_one)] +/// use std::hash::BuildHasher; /// /// let b = std::collections::hash_map::RandomState::new(); /// let a: [u8; 3] = [0xa8, 0x3c, 0x09]; /// let s: &[u8] = &[0xa8, 0x3c, 0x09]; -/// assert_eq!(hash_of(a, &b), hash_of(s, &b)); +/// assert_eq!(b.hash_one(a), b.hash_one(s)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] impl Hash for [T; N] { diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 77d3a35b26822..9dbefe0822e36 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -481,6 +481,50 @@ pub trait BuildHasher { /// ``` #[stable(since = "1.7.0", feature = "build_hasher")] fn build_hasher(&self) -> Self::Hasher; + + /// Calculates the hash of a single value. + /// + /// This is intended as a convenience for code which *consumes* hashes, such + /// as the implementation of a hash table or in unit tests that check + /// whether a custom [`Hash`] implementation behaves as expected. + /// + /// This must not be used in any code which *creates* hashes, such as in an + /// implementation of [`Hash`]. The way to create a combined hash of + /// multiple values is to call [`Hash::hash`] multiple times using the same + /// [`Hasher`], not to call this method repeatedly and combine the results. + /// + /// # Example + /// + /// ``` + /// #![feature(build_hasher_simple_hash_one)] + /// + /// use std::cmp::{max, min}; + /// use std::hash::{BuildHasher, Hash, Hasher}; + /// struct OrderAmbivalentPair(T, T); + /// impl Hash for OrderAmbivalentPair { + /// fn hash(&self, hasher: &mut H) { + /// min(&self.0, &self.1).hash(hasher); + /// max(&self.0, &self.1).hash(hasher); + /// } + /// } + /// + /// // Then later, in a `#[test]` for the type... + /// let bh = std::collections::hash_map::RandomState::new(); + /// assert_eq!( + /// bh.hash_one(OrderAmbivalentPair(1, 2)), + /// bh.hash_one(OrderAmbivalentPair(2, 1)) + /// ); + /// assert_eq!( + /// bh.hash_one(OrderAmbivalentPair(10, 2)), + /// bh.hash_one(&OrderAmbivalentPair(2, 10)) + /// ); + /// ``` + #[unstable(feature = "build_hasher_simple_hash_one", issue = "86161")] + fn hash_one(&self, x: T) -> u64 { + let mut hasher = self.build_hasher(); + x.hash(&mut hasher); + hasher.finish() + } } /// Used to create a default [`BuildHasher`] instance for types that implement