about summary refs log tree commit diff
diff options
context:
space:
mode:
authorltdk <usr@ltdk.xyz>2021-03-22 15:39:22 -0400
committerltdk <usr@ltdk.xyz>2021-04-26 01:11:46 -0400
commit920de7dd94dbc81988de596aeed9a812498bdeab (patch)
tree92156d95bbf488549a694bc729dee8069661e596
parent1a6c98e4d6f6338dac2357b9433af8ef2a6ba320 (diff)
downloadrust-920de7dd94dbc81988de596aeed9a812498bdeab.tar.gz
rust-920de7dd94dbc81988de596aeed9a812498bdeab.zip
Document Hasher spec decision from #42951
-rw-r--r--library/core/src/hash/mod.rs27
1 files changed, 27 insertions, 0 deletions
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index 0c3303cc210..20eb955ff6c 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -175,6 +175,21 @@ pub trait Hash {
 
     /// Feeds a slice of this type into the given [`Hasher`].
     ///
+    /// This method is meant as a convenience, but its implementation is
+    /// also explicitly left unspecified. It isn't guaranteed to be
+    /// equivalent to repeated calls of [`hash`] and implementations of
+    /// [`Hash`] should keep that in mind and call [`hash`] themselves
+    /// if the slice isn't treated as a whole unit in the [`PartialEq`]
+    /// implementation.
+    ///
+    /// For example, a [`VecDeque`] implementation might naïvely call
+    /// [`as_slices`] and then [`hash_slice`] on each slice, but this
+    /// is wrong since the two slices can change with a call to
+    /// [`make_contiguous`] without affecting the [`PartialEq`]
+    /// result. Since these slices aren't treated as singular
+    /// units, and instead part of a larger deque, this method cannot
+    /// be used.
+    ///
     /// # Examples
     ///
     /// ```
@@ -186,6 +201,12 @@ pub trait Hash {
     /// Hash::hash_slice(&numbers, &mut hasher);
     /// println!("Hash is {:x}!", hasher.finish());
     /// ```
+    ///
+    /// [`VecDeque`]: ../../std/collections/struct.VecDeque.html
+    /// [`as_slices`]: ../../std/collections/struct.VecDeque.html#method.as_slices
+    /// [`make_contiguous`]: ../../std/collections/struct.VecDeque.html#method.make_contiguous
+    /// [`hash`]: Hash::hash
+    /// [`hash_slice`]: Hash::hash_slice
     #[stable(feature = "hash_slice", since = "1.3.0")]
     fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
     where
@@ -221,6 +242,11 @@ pub use macros::Hash;
 /// instance (with [`write`] and [`write_u8`] etc.). Most of the time, `Hasher`
 /// instances are used in conjunction with the [`Hash`] trait.
 ///
+/// This trait makes no assumptions about how the various `write_*` methods are
+/// defined and implementations of [`Hash`] should not assume that they work one
+/// way or another. You cannot assume, for example, that a [`write_u32`] call is
+/// equivalent to four calls of [`write_u8`].
+///
 /// # Examples
 ///
 /// ```
@@ -240,6 +266,7 @@ pub use macros::Hash;
 /// [`finish`]: Hasher::finish
 /// [`write`]: Hasher::write
 /// [`write_u8`]: Hasher::write_u8
+/// [`write_u32`]: Hasher::write_u32
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Hasher {
     /// Returns the hash value for the values written so far.