From 4c93668f03ea7d6dbf5fd9d6d109ee5d87a43f72 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 8 Jun 2021 00:19:52 -0700 Subject: [PATCH] Hash arrays via `Hash::hash_slice` instead of via `<[T]>::hash` --- library/core/src/array/mod.rs | 9 ++++++++- library/core/tests/array.rs | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index e25d006d213c7..9f8037291a329 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -139,10 +139,17 @@ impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] { } } +/// Note that `Hash` for arrays provides no guarantees on its behavior other +/// than the consistency with `Eq` required by the trait, and its implementation +/// may change between rust versions. +/// +/// For example, the hash of the array `[x, y, z]` may or may not be the same as +/// the hash of the tuple `(x, y, z)`, and the hash of the array `[x, y, z]` may +/// or may not be the same as the hash of the vector `vec![x, y, z]`. #[stable(feature = "rust1", since = "1.0.0")] impl Hash for [T; N] { fn hash(&self, state: &mut H) { - Hash::hash(&self[..], state) + Hash::hash_slice(&self[..], state) } } diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index ce7480ce2ee89..29304948c0330 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -356,3 +356,24 @@ fn cell_allows_array_cycle() { b3.a[0].set(Some(&b1)); b3.a[1].set(Some(&b2)); } + +#[test] +fn hashing_array_does_not_hash_length() { + use core::hash::{Hash, Hasher}; + + struct PanicOnHashUsize(usize); + impl Hasher for PanicOnHashUsize { + fn finish(&self) -> u64 { + self.0 as _ + } + fn write(&mut self, bytes: &[u8]) { + assert!(bytes.len() < core::mem::size_of::()); + self.0 += bytes.len(); + } + } + + let mut h = PanicOnHashUsize(0); + let a: [u8; 1] = [42]; + a.hash(&mut h); + assert_eq!(h.finish(), 1); +}