File tree 2 files changed +47
-3
lines changed
library/alloc/src/collections/vec_deque
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> {
2646
2646
impl < A : Hash > Hash for VecDeque < A > {
2647
2647
fn hash < H : Hasher > ( & self , state : & mut H ) {
2648
2648
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) ) ;
2652
2656
}
2653
2657
}
2654
2658
Original file line number Diff line number Diff line change @@ -599,3 +599,43 @@ fn issue_53529() {
599
599
assert_eq ! ( * a, 2 ) ;
600
600
}
601
601
}
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