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