parent
66eb982166
commit
ae3a515337
2 changed files with 47 additions and 3 deletions
|
@ -2646,9 +2646,13 @@ impl<A: Ord> Ord for VecDeque<A> {
|
||||||
impl<A: Hash> Hash for VecDeque<A> {
|
impl<A: Hash> Hash for VecDeque<A> {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.len().hash(state);
|
self.len().hash(state);
|
||||||
let (a, b) = self.as_slices();
|
// It's not possible to use Hash::hash_slice on slices
|
||||||
Hash::hash_slice(a, state);
|
// returned by as_slices method as their length can vary
|
||||||
Hash::hash_slice(b, state);
|
// in otherwise identical deques.
|
||||||
|
//
|
||||||
|
// Hasher only guarantees equivalence for the exact same
|
||||||
|
// set of calls to its methods.
|
||||||
|
self.iter().for_each(|elem| elem.hash(state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -599,3 +599,43 @@ fn issue_53529() {
|
||||||
assert_eq!(*a, 2);
|
assert_eq!(*a, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn issue_80303() {
|
||||||
|
use core::iter;
|
||||||
|
use core::num::Wrapping;
|
||||||
|
|
||||||
|
// This is a valid, albeit rather bad hash function implementation.
|
||||||
|
struct SimpleHasher(Wrapping<u64>);
|
||||||
|
|
||||||
|
impl Hasher for SimpleHasher {
|
||||||
|
fn finish(&self) -> u64 {
|
||||||
|
self.0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, bytes: &[u8]) {
|
||||||
|
// This particular implementation hashes value 24 in addition to bytes.
|
||||||
|
// Such an implementation is valid as Hasher only guarantees equivalence
|
||||||
|
// for the exact same set of calls to its methods.
|
||||||
|
for &v in iter::once(&24).chain(bytes) {
|
||||||
|
self.0 = Wrapping(31) * self.0 + Wrapping(u64::from(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash_code(value: impl Hash) -> u64 {
|
||||||
|
let mut hasher = SimpleHasher(Wrapping(1));
|
||||||
|
value.hash(&mut hasher);
|
||||||
|
hasher.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
// This creates two deques for which values returned by as_slices
|
||||||
|
// method differ.
|
||||||
|
let vda: VecDeque<u8> = (0..10).collect();
|
||||||
|
let mut vdb = VecDeque::with_capacity(10);
|
||||||
|
vdb.extend(5..10);
|
||||||
|
(0..5).rev().for_each(|elem| vdb.push_front(elem));
|
||||||
|
assert_ne!(vda.as_slices(), vdb.as_slices());
|
||||||
|
assert_eq!(vda, vdb);
|
||||||
|
assert_eq!(hash_code(vda), hash_code(vdb));
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue