File tree Expand file tree Collapse file tree 2 files changed +47
-3
lines changed
library/alloc/src/collections/vec_deque Expand file tree Collapse file tree 2 files changed +47
-3
lines changed Original file line number Diff line number Diff line change @@ -2646,9 +2646,13 @@ impl<A: Ord> Ord for VecDeque<A> {
26462646impl<A: Hash> Hash for VecDeque<A> {
26472647 fn hash<H: Hasher>(&self, state: &mut H) {
26482648 self.len().hash(state);
2649- let (a, b) = self.as_slices();
2650- Hash::hash_slice(a, state);
2651- Hash::hash_slice(b, state);
2649+ // It's not possible to use Hash::hash_slice on slices
2650+ // returned by as_slices method as their length can vary
2651+ // in otherwise identical deques.
2652+ //
2653+ // Hasher only guarantees equivalence for the exact same
2654+ // set of calls to its methods.
2655+ self.iter().for_each(|elem| elem.hash(state));
26522656 }
26532657}
26542658
Original file line number Diff line number Diff line change @@ -599,3 +599,43 @@ fn issue_53529() {
599599 assert_eq!(*a, 2);
600600 }
601601}
602+
603+ #[test]
604+ fn issue_80303() {
605+ use core::iter;
606+ use core::num::Wrapping;
607+
608+ // This is a valid, albeit rather bad hash function implementation.
609+ struct SimpleHasher(Wrapping<u64>);
610+
611+ impl Hasher for SimpleHasher {
612+ fn finish(&self) -> u64 {
613+ self.0.0
614+ }
615+
616+ fn write(&mut self, bytes: &[u8]) {
617+ // This particular implementation hashes value 24 in addition to bytes.
618+ // Such an implementation is valid as Hasher only guarantees equivalence
619+ // for the exact same set of calls to its methods.
620+ for &v in iter::once(&24).chain(bytes) {
621+ self.0 = Wrapping(31) * self.0 + Wrapping(u64::from(v));
622+ }
623+ }
624+ }
625+
626+ fn hash_code(value: impl Hash) -> u64 {
627+ let mut hasher = SimpleHasher(Wrapping(1));
628+ value.hash(&mut hasher);
629+ hasher.finish()
630+ }
631+
632+ // This creates two deques for which values returned by as_slices
633+ // method differ.
634+ let vda: VecDeque<u8> = (0..10).collect();
635+ let mut vdb = VecDeque::with_capacity(10);
636+ vdb.extend(5..10);
637+ (0..5).rev().for_each(|elem| vdb.push_front(elem));
638+ assert_ne!(vda.as_slices(), vdb.as_slices());
639+ assert_eq!(vda, vdb);
640+ assert_eq!(hash_code(vda), hash_code(vdb));
641+ }
You can’t perform that action at this time.
0 commit comments