From a3eb9e3db2af13cb8c8a7542ae94514228a5417c Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 8 Jun 2021 13:52:57 -0700 Subject: [PATCH 1/3] Add `BuildHasher::hash_of` as unstable --- library/core/src/hash/mod.rs | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 77d3a35b26822..28f98d983c768 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_of)] + /// + /// 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_of(OrderAmbivalentPair(1, 2)), + /// bh.hash_of(OrderAmbivalentPair(2, 1)) + /// ); + /// assert_eq!( + /// bh.hash_of(OrderAmbivalentPair(10, 2)), + /// bh.hash_of(&OrderAmbivalentPair(2, 10)) + /// ); + /// ``` + #[unstable(feature = "build_hasher_simple_hash_of", issue = "88888888")] + fn hash_of(&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 From 63d28192daf0ac2c704f4893d81ff32e1562e3c1 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 8 Jun 2021 22:07:14 -0700 Subject: [PATCH 2/3] Add tracking issue and rename to hash_one --- library/core/src/hash/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 28f98d983c768..9dbefe0822e36 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -496,7 +496,7 @@ pub trait BuildHasher { /// # Example /// /// ``` - /// #![feature(build_hasher_simple_hash_of)] + /// #![feature(build_hasher_simple_hash_one)] /// /// use std::cmp::{max, min}; /// use std::hash::{BuildHasher, Hash, Hasher}; @@ -511,16 +511,16 @@ pub trait BuildHasher { /// // Then later, in a `#[test]` for the type... /// let bh = std::collections::hash_map::RandomState::new(); /// assert_eq!( - /// bh.hash_of(OrderAmbivalentPair(1, 2)), - /// bh.hash_of(OrderAmbivalentPair(2, 1)) + /// bh.hash_one(OrderAmbivalentPair(1, 2)), + /// bh.hash_one(OrderAmbivalentPair(2, 1)) /// ); /// assert_eq!( - /// bh.hash_of(OrderAmbivalentPair(10, 2)), - /// bh.hash_of(&OrderAmbivalentPair(2, 10)) + /// bh.hash_one(OrderAmbivalentPair(10, 2)), + /// bh.hash_one(&OrderAmbivalentPair(2, 10)) /// ); /// ``` - #[unstable(feature = "build_hasher_simple_hash_of", issue = "88888888")] - fn hash_of(&self, x: T) -> u64 { + #[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() From 579d19bc6ac91548e8b256656ca1d7fbceb53197 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 24 Jun 2021 01:30:08 -0700 Subject: [PATCH 3/3] Use `hash_one` to simplify some other doctests --- library/alloc/src/vec/mod.rs | 11 +++-------- library/core/src/array/mod.rs | 11 +++-------- 2 files changed, 6 insertions(+), 16 deletions(-) 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] {