1 use super::Entry
::{Occupied, Vacant}
;
3 use super::RandomState
;
4 use crate::assert_matches
::assert_matches
;
5 use crate::cell
::RefCell
;
6 use crate::test_helpers
::test_rng
;
8 use realstd
::collections
::TryReserveErrorKind
::*;
10 // https://github.com/rust-lang/rust/issues/62301
11 fn _assert_hashmap_is_unwind_safe() {
12 fn assert_unwind_safe
<T
: crate::panic
::UnwindSafe
>() {}
13 assert_unwind_safe
::<HashMap
<(), crate::cell
::UnsafeCell
<()>>>();
17 fn test_zero_capacities() {
18 type HM
= HashMap
<i32, i32>;
21 assert_eq
!(m
.capacity(), 0);
23 let m
= HM
::default();
24 assert_eq
!(m
.capacity(), 0);
26 let m
= HM
::with_hasher(RandomState
::new());
27 assert_eq
!(m
.capacity(), 0);
29 let m
= HM
::with_capacity(0);
30 assert_eq
!(m
.capacity(), 0);
32 let m
= HM
::with_capacity_and_hasher(0, RandomState
::new());
33 assert_eq
!(m
.capacity(), 0);
35 let mut m
= HM
::new();
41 assert_eq
!(m
.capacity(), 0);
43 let mut m
= HM
::new();
45 assert_eq
!(m
.capacity(), 0);
49 fn test_create_capacity_zero() {
50 let mut m
= HashMap
::with_capacity(0);
52 assert
!(m
.insert(1, 1).is_none());
54 assert
!(m
.contains_key(&1));
55 assert
!(!m
.contains_key(&0));
60 let mut m
= HashMap
::new();
61 assert_eq
!(m
.len(), 0);
62 assert
!(m
.insert(1, 2).is_none());
63 assert_eq
!(m
.len(), 1);
64 assert
!(m
.insert(2, 4).is_none());
65 assert_eq
!(m
.len(), 2);
66 assert_eq
!(*m
.get(&1).unwrap(), 2);
67 assert_eq
!(*m
.get(&2).unwrap(), 4);
72 let mut m
= HashMap
::new();
73 assert_eq
!(m
.len(), 0);
74 assert
!(m
.insert(1, 2).is_none());
75 assert_eq
!(m
.len(), 1);
76 assert
!(m
.insert(2, 4).is_none());
77 assert_eq
!(m
.len(), 2);
79 assert_eq
!(*m2
.get(&1).unwrap(), 2);
80 assert_eq
!(*m2
.get(&2).unwrap(), 4);
81 assert_eq
!(m2
.len(), 2);
84 thread_local
! { static DROP_VECTOR: RefCell<Vec<i32>> = RefCell::new(Vec::new()) }
86 #[derive(Hash, PartialEq, Eq)]
92 fn new(k
: usize) -> Droppable
{
93 DROP_VECTOR
.with(|slot
| {
94 slot
.borrow_mut()[k
] += 1;
101 impl Drop
for Droppable
{
103 DROP_VECTOR
.with(|slot
| {
104 slot
.borrow_mut()[self.k
] -= 1;
109 impl Clone
for Droppable
{
110 fn clone(&self) -> Droppable
{
111 Droppable
::new(self.k
)
117 DROP_VECTOR
.with(|slot
| {
118 *slot
.borrow_mut() = vec
![0; 200];
122 let mut m
= HashMap
::new();
124 DROP_VECTOR
.with(|v
| {
126 assert_eq
!(v
.borrow()[i
], 0);
131 let d1
= Droppable
::new(i
);
132 let d2
= Droppable
::new(i
+ 100);
136 DROP_VECTOR
.with(|v
| {
138 assert_eq
!(v
.borrow()[i
], 1);
143 let k
= Droppable
::new(i
);
144 let v
= m
.remove(&k
);
146 assert
!(v
.is_some());
148 DROP_VECTOR
.with(|v
| {
149 assert_eq
!(v
.borrow()[i
], 1);
150 assert_eq
!(v
.borrow()[i
+ 100], 1);
154 DROP_VECTOR
.with(|v
| {
156 assert_eq
!(v
.borrow()[i
], 0);
157 assert_eq
!(v
.borrow()[i
+ 100], 0);
161 assert_eq
!(v
.borrow()[i
], 1);
162 assert_eq
!(v
.borrow()[i
+ 100], 1);
167 DROP_VECTOR
.with(|v
| {
169 assert_eq
!(v
.borrow()[i
], 0);
175 fn test_into_iter_drops() {
176 DROP_VECTOR
.with(|v
| {
177 *v
.borrow_mut() = vec
![0; 200];
181 let mut hm
= HashMap
::new();
183 DROP_VECTOR
.with(|v
| {
185 assert_eq
!(v
.borrow()[i
], 0);
190 let d1
= Droppable
::new(i
);
191 let d2
= Droppable
::new(i
+ 100);
195 DROP_VECTOR
.with(|v
| {
197 assert_eq
!(v
.borrow()[i
], 1);
204 // By the way, ensure that cloning doesn't screw up the dropping.
208 let mut half
= hm
.into_iter().take(50);
210 DROP_VECTOR
.with(|v
| {
212 assert_eq
!(v
.borrow()[i
], 1);
216 for _
in half
.by_ref() {}
218 DROP_VECTOR
.with(|v
| {
219 let nk
= (0..100).filter(|&i
| v
.borrow()[i
] == 1).count();
221 let nv
= (0..100).filter(|&i
| v
.borrow()[i
+ 100] == 1).count();
228 DROP_VECTOR
.with(|v
| {
230 assert_eq
!(v
.borrow()[i
], 0);
236 fn test_empty_remove() {
237 let mut m
: HashMap
<i32, bool
> = HashMap
::new();
238 assert_eq
!(m
.remove(&0), None
);
242 fn test_empty_entry() {
243 let mut m
: HashMap
<i32, bool
> = HashMap
::new();
245 Occupied(_
) => panic
!(),
248 assert
!(*m
.entry(0).or_insert(true));
249 assert_eq
!(m
.len(), 1);
253 fn test_empty_iter() {
254 let mut m
: HashMap
<i32, bool
> = HashMap
::new();
255 assert_eq
!(m
.drain().next(), None
);
256 assert_eq
!(m
.keys().next(), None
);
257 assert_eq
!(m
.values().next(), None
);
258 assert_eq
!(m
.values_mut().next(), None
);
259 assert_eq
!(m
.iter().next(), None
);
260 assert_eq
!(m
.iter_mut().next(), None
);
261 assert_eq
!(m
.len(), 0);
262 assert
!(m
.is_empty());
263 assert_eq
!(m
.into_iter().next(), None
);
267 fn test_lots_of_insertions() {
268 let mut m
= HashMap
::new();
270 // Try this a few times to make sure we never screw up the hashmap's
272 let loops
= if cfg
!(miri
) { 2 }
else { 10 }
;
274 assert
!(m
.is_empty());
276 let count
= if cfg
!(miri
) { 101 }
else { 1001 }
;
279 assert
!(m
.insert(i
, i
).is_none());
283 assert_eq
!(r
, Some(&j
));
286 for j
in i
+ 1..count
{
292 for i
in count
..(2 * count
) {
293 assert
!(!m
.contains_key(&i
));
298 assert
!(m
.remove(&i
).is_some());
301 assert
!(!m
.contains_key(&j
));
304 for j
in i
+ 1..count
{
305 assert
!(m
.contains_key(&j
));
310 assert
!(!m
.contains_key(&i
));
314 assert
!(m
.insert(i
, i
).is_none());
318 for i
in (1..count
).rev() {
319 assert
!(m
.remove(&i
).is_some());
322 assert
!(!m
.contains_key(&j
));
326 assert
!(m
.contains_key(&j
));
334 let mut m
= HashMap
::new();
335 assert
!(m
.insert(1, 12).is_none());
336 assert
!(m
.insert(2, 8).is_none());
337 assert
!(m
.insert(5, 14).is_none());
339 match m
.get_mut(&5) {
343 assert_eq
!(m
.get(&5), Some(&new
));
347 fn test_insert_overwrite() {
348 let mut m
= HashMap
::new();
349 assert
!(m
.insert(1, 2).is_none());
350 assert_eq
!(*m
.get(&1).unwrap(), 2);
351 assert
!(!m
.insert(1, 3).is_none());
352 assert_eq
!(*m
.get(&1).unwrap(), 3);
356 fn test_insert_conflicts() {
357 let mut m
= HashMap
::with_capacity(4);
358 assert
!(m
.insert(1, 2).is_none());
359 assert
!(m
.insert(5, 3).is_none());
360 assert
!(m
.insert(9, 4).is_none());
361 assert_eq
!(*m
.get(&9).unwrap(), 4);
362 assert_eq
!(*m
.get(&5).unwrap(), 3);
363 assert_eq
!(*m
.get(&1).unwrap(), 2);
367 fn test_conflict_remove() {
368 let mut m
= HashMap
::with_capacity(4);
369 assert
!(m
.insert(1, 2).is_none());
370 assert_eq
!(*m
.get(&1).unwrap(), 2);
371 assert
!(m
.insert(5, 3).is_none());
372 assert_eq
!(*m
.get(&1).unwrap(), 2);
373 assert_eq
!(*m
.get(&5).unwrap(), 3);
374 assert
!(m
.insert(9, 4).is_none());
375 assert_eq
!(*m
.get(&1).unwrap(), 2);
376 assert_eq
!(*m
.get(&5).unwrap(), 3);
377 assert_eq
!(*m
.get(&9).unwrap(), 4);
378 assert
!(m
.remove(&1).is_some());
379 assert_eq
!(*m
.get(&9).unwrap(), 4);
380 assert_eq
!(*m
.get(&5).unwrap(), 3);
385 let mut m
= HashMap
::with_capacity(4);
386 assert
!(m
.insert(1, 2).is_none());
387 assert
!(!m
.is_empty());
388 assert
!(m
.remove(&1).is_some());
389 assert
!(m
.is_empty());
394 let mut m
= HashMap
::new();
396 assert_eq
!(m
.remove(&1), Some(2));
397 assert_eq
!(m
.remove(&1), None
);
401 fn test_remove_entry() {
402 let mut m
= HashMap
::new();
404 assert_eq
!(m
.remove_entry(&1), Some((1, 2)));
405 assert_eq
!(m
.remove(&1), None
);
410 let mut m
= HashMap
::with_capacity(4);
412 assert
!(m
.insert(i
, i
* 2).is_none());
414 assert_eq
!(m
.len(), 32);
416 let mut observed
: u32 = 0;
419 assert_eq
!(*v
, *k
* 2);
422 assert_eq
!(observed
, 0xFFFF_FFFF);
427 let pairs
= [(1, 'a'
), (2, 'b'
), (3, 'c'
)];
428 let map
: HashMap
<_
, _
> = pairs
.into_iter().collect();
429 let keys
: Vec
<_
> = map
.keys().cloned().collect();
430 assert_eq
!(keys
.len(), 3);
431 assert
!(keys
.contains(&1));
432 assert
!(keys
.contains(&2));
433 assert
!(keys
.contains(&3));
438 let pairs
= [(1, 'a'
), (2, 'b'
), (3, 'c'
)];
439 let map
: HashMap
<_
, _
> = pairs
.into_iter().collect();
440 let values
: Vec
<_
> = map
.values().cloned().collect();
441 assert_eq
!(values
.len(), 3);
442 assert
!(values
.contains(&'a'
));
443 assert
!(values
.contains(&'b'
));
444 assert
!(values
.contains(&'c'
));
448 fn test_values_mut() {
449 let pairs
= [(1, 1), (2, 2), (3, 3)];
450 let mut map
: HashMap
<_
, _
> = pairs
.into_iter().collect();
451 for value
in map
.values_mut() {
452 *value
= (*value
) * 2
454 let values
: Vec
<_
> = map
.values().cloned().collect();
455 assert_eq
!(values
.len(), 3);
456 assert
!(values
.contains(&2));
457 assert
!(values
.contains(&4));
458 assert
!(values
.contains(&6));
462 fn test_into_keys() {
463 let pairs
= [(1, 'a'
), (2, 'b'
), (3, 'c'
)];
464 let map
: HashMap
<_
, _
> = pairs
.into_iter().collect();
465 let keys
: Vec
<_
> = map
.into_keys().collect();
467 assert_eq
!(keys
.len(), 3);
468 assert
!(keys
.contains(&1));
469 assert
!(keys
.contains(&2));
470 assert
!(keys
.contains(&3));
474 fn test_into_values() {
475 let pairs
= [(1, 'a'
), (2, 'b'
), (3, 'c'
)];
476 let map
: HashMap
<_
, _
> = pairs
.into_iter().collect();
477 let values
: Vec
<_
> = map
.into_values().collect();
479 assert_eq
!(values
.len(), 3);
480 assert
!(values
.contains(&'a'
));
481 assert
!(values
.contains(&'b'
));
482 assert
!(values
.contains(&'c'
));
487 let mut m
= HashMap
::new();
488 assert
!(m
.get(&1).is_none());
492 Some(v
) => assert_eq
!(*v
, 2),
498 let mut m1
= HashMap
::new();
503 let mut m2
= HashMap
::new();
516 let mut map
= HashMap
::new();
517 let empty
: HashMap
<i32, i32> = HashMap
::new();
522 let map_str
= format
!("{map:?}");
524 assert
!(map_str
== "{1: 2, 3: 4}" || map_str
== "{3: 4, 1: 2}");
525 assert_eq
!(format
!("{empty:?}"), "{}");
529 fn test_reserve_shrink_to_fit() {
530 let mut m
= HashMap
::new();
533 assert
!(m
.capacity() >= m
.len());
539 let usable_cap
= m
.capacity();
540 for i
in 128..(128 + 256) {
542 assert_eq
!(m
.capacity(), usable_cap
);
545 for i
in 100..(128 + 256) {
546 assert_eq
!(m
.remove(&i
), Some(i
));
550 assert_eq
!(m
.len(), 100);
551 assert
!(!m
.is_empty());
552 assert
!(m
.capacity() >= m
.len());
555 assert_eq
!(m
.remove(&i
), Some(i
));
560 assert_eq
!(m
.len(), 1);
561 assert
!(m
.capacity() >= m
.len());
562 assert_eq
!(m
.remove(&0), Some(0));
566 fn test_from_iter() {
567 let xs
= [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
569 let map
: HashMap
<_
, _
> = xs
.iter().cloned().collect();
572 assert_eq
!(map
.get(&k
), Some(&v
));
575 assert_eq
!(map
.iter().len(), xs
.len() - 1);
579 fn test_size_hint() {
580 let xs
= [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
582 let map
: HashMap
<_
, _
> = xs
.iter().cloned().collect();
584 let mut iter
= map
.iter();
586 for _
in iter
.by_ref().take(3) {}
588 assert_eq
!(iter
.size_hint(), (3, Some(3)));
593 let xs
= [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
595 let map
: HashMap
<_
, _
> = xs
.iter().cloned().collect();
597 let mut iter
= map
.iter();
599 for _
in iter
.by_ref().take(3) {}
601 assert_eq
!(iter
.len(), 3);
605 fn test_mut_size_hint() {
606 let xs
= [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
608 let mut map
: HashMap
<_
, _
> = xs
.iter().cloned().collect();
610 let mut iter
= map
.iter_mut();
612 for _
in iter
.by_ref().take(3) {}
614 assert_eq
!(iter
.size_hint(), (3, Some(3)));
618 fn test_iter_mut_len() {
619 let xs
= [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
621 let mut map
: HashMap
<_
, _
> = xs
.iter().cloned().collect();
623 let mut iter
= map
.iter_mut();
625 for _
in iter
.by_ref().take(3) {}
627 assert_eq
!(iter
.len(), 3);
632 let mut map
= HashMap
::new();
638 assert_eq
!(map
[&2], 1);
643 fn test_index_nonexistent() {
644 let mut map
= HashMap
::new();
655 let xs
= [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
657 let mut map
: HashMap
<_
, _
> = xs
.iter().cloned().collect();
659 // Existing key (insert)
661 Vacant(_
) => unreachable
!(),
662 Occupied(mut view
) => {
663 assert_eq
!(view
.get(), &10);
664 assert_eq
!(view
.insert(100), 10);
667 assert_eq
!(map
.get(&1).unwrap(), &100);
668 assert_eq
!(map
.len(), 6);
670 // Existing key (update)
672 Vacant(_
) => unreachable
!(),
673 Occupied(mut view
) => {
674 let v
= view
.get_mut();
675 let new_v
= (*v
) * 10;
679 assert_eq
!(map
.get(&2).unwrap(), &200);
680 assert_eq
!(map
.len(), 6);
682 // Existing key (take)
684 Vacant(_
) => unreachable
!(),
686 assert_eq
!(view
.remove(), 30);
689 assert_eq
!(map
.get(&3), None
);
690 assert_eq
!(map
.len(), 5);
692 // Inexistent key (insert)
693 match map
.entry(10) {
694 Occupied(_
) => unreachable
!(),
696 assert_eq
!(*view
.insert(1000), 1000);
699 assert_eq
!(map
.get(&10).unwrap(), &1000);
700 assert_eq
!(map
.len(), 6);
704 fn test_entry_take_doesnt_corrupt() {
705 #![allow(deprecated)] //rand
707 fn check(m
: &HashMap
<i32, ()>) {
709 assert
!(m
.contains_key(k
), "{k} is in keys() but not in the map?");
713 let mut m
= HashMap
::new();
714 let mut rng
= test_rng();
716 // Populate the map with some items.
718 let x
= rng
.gen_range(-10..10);
723 let x
= rng
.gen_range(-10..10);
736 fn test_extend_ref() {
737 let mut a
= HashMap
::new();
739 let mut b
= HashMap
::new();
741 b
.insert(3, "three");
745 assert_eq
!(a
.len(), 3);
746 assert_eq
!(a
[&1], "one");
747 assert_eq
!(a
[&2], "two");
748 assert_eq
!(a
[&3], "three");
752 fn test_capacity_not_less_than_len() {
753 let mut a
= HashMap
::new();
761 assert
!(a
.capacity() > a
.len());
763 let free
= a
.capacity() - a
.len();
769 assert_eq
!(a
.len(), a
.capacity());
771 // Insert at capacity should cause allocation.
773 assert
!(a
.capacity() > a
.len());
777 fn test_occupied_entry_key() {
778 let mut a
= HashMap
::new();
779 let key
= "hello there";
780 let value
= "value goes here";
781 assert
!(a
.is_empty());
782 a
.insert(key
, value
);
783 assert_eq
!(a
.len(), 1);
784 assert_eq
!(a
[key
], value
);
787 Vacant(_
) => panic
!(),
788 Occupied(e
) => assert_eq
!(key
, *e
.key()),
790 assert_eq
!(a
.len(), 1);
791 assert_eq
!(a
[key
], value
);
795 fn test_vacant_entry_key() {
796 let mut a
= HashMap
::new();
797 let key
= "hello there";
798 let value
= "value goes here";
800 assert
!(a
.is_empty());
802 Occupied(_
) => panic
!(),
804 assert_eq
!(key
, *e
.key());
808 assert_eq
!(a
.len(), 1);
809 assert_eq
!(a
[key
], value
);
814 let mut map
: HashMap
<i32, i32> = (0..100).map(|x
| (x
, x
* 10)).collect();
816 map
.retain(|&k
, _
| k
% 2 == 0);
817 assert_eq
!(map
.len(), 50);
818 assert_eq
!(map
[&2], 20);
819 assert_eq
!(map
[&4], 40);
820 assert_eq
!(map
[&6], 60);
824 #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
825 #[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
826 fn test_try_reserve() {
827 let mut empty_bytes
: HashMap
<u8, u8> = HashMap
::new();
829 const MAX_USIZE
: usize = usize::MAX
;
832 empty_bytes
.try_reserve(MAX_USIZE
).map_err(|e
| e
.kind()),
833 Err(CapacityOverflow
),
834 "usize::MAX should trigger an overflow!"
837 if let Err(AllocError { .. }
) = empty_bytes
.try_reserve(MAX_USIZE
/ 16).map_err(|e
| e
.kind()) {
839 // This may succeed if there is enough free memory. Attempt to
840 // allocate a few more hashmaps to ensure the allocation will fail.
841 let mut empty_bytes2
: HashMap
<u8, u8> = HashMap
::new();
842 let _
= empty_bytes2
.try_reserve(MAX_USIZE
/ 16);
843 let mut empty_bytes3
: HashMap
<u8, u8> = HashMap
::new();
844 let _
= empty_bytes3
.try_reserve(MAX_USIZE
/ 16);
845 let mut empty_bytes4
: HashMap
<u8, u8> = HashMap
::new();
847 empty_bytes4
.try_reserve(MAX_USIZE
/ 16).map_err(|e
| e
.kind()),
848 Err(AllocError { .. }
),
849 "usize::MAX / 16 should trigger an OOM!"
855 fn test_raw_entry() {
856 use super::RawEntryMut
::{Occupied, Vacant}
;
858 let xs
= [(1i32, 10i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
860 let mut map
: HashMap
<_
, _
> = xs
.iter().cloned().collect();
862 let compute_hash
= |map
: &HashMap
<i32, i32>, k
: i32| -> u64 {
863 use core
::hash
::{BuildHasher, Hash, Hasher}
;
865 let mut hasher
= map
.hasher().build_hasher();
870 // Existing key (insert)
871 match map
.raw_entry_mut().from_key(&1) {
872 Vacant(_
) => unreachable
!(),
873 Occupied(mut view
) => {
874 assert_eq
!(view
.get(), &10);
875 assert_eq
!(view
.insert(100), 10);
878 let hash1
= compute_hash(&map
, 1);
879 assert_eq
!(map
.raw_entry().from_key(&1).unwrap(), (&1, &100));
880 assert_eq
!(map
.raw_entry().from_hash(hash1
, |k
| *k
== 1).unwrap(), (&1, &100));
881 assert_eq
!(map
.raw_entry().from_key_hashed_nocheck(hash1
, &1).unwrap(), (&1, &100));
882 assert_eq
!(map
.len(), 6);
884 // Existing key (update)
885 match map
.raw_entry_mut().from_key(&2) {
886 Vacant(_
) => unreachable
!(),
887 Occupied(mut view
) => {
888 let v
= view
.get_mut();
889 let new_v
= (*v
) * 10;
893 let hash2
= compute_hash(&map
, 2);
894 assert_eq
!(map
.raw_entry().from_key(&2).unwrap(), (&2, &200));
895 assert_eq
!(map
.raw_entry().from_hash(hash2
, |k
| *k
== 2).unwrap(), (&2, &200));
896 assert_eq
!(map
.raw_entry().from_key_hashed_nocheck(hash2
, &2).unwrap(), (&2, &200));
897 assert_eq
!(map
.len(), 6);
899 // Existing key (take)
900 let hash3
= compute_hash(&map
, 3);
901 match map
.raw_entry_mut().from_key_hashed_nocheck(hash3
, &3) {
902 Vacant(_
) => unreachable
!(),
904 assert_eq
!(view
.remove_entry(), (3, 30));
907 assert_eq
!(map
.raw_entry().from_key(&3), None
);
908 assert_eq
!(map
.raw_entry().from_hash(hash3
, |k
| *k
== 3), None
);
909 assert_eq
!(map
.raw_entry().from_key_hashed_nocheck(hash3
, &3), None
);
910 assert_eq
!(map
.len(), 5);
912 // Nonexistent key (insert)
913 match map
.raw_entry_mut().from_key(&10) {
914 Occupied(_
) => unreachable
!(),
916 assert_eq
!(view
.insert(10, 1000), (&mut 10, &mut 1000));
919 assert_eq
!(map
.raw_entry().from_key(&10).unwrap(), (&10, &1000));
920 assert_eq
!(map
.len(), 6);
922 // Ensure all lookup methods produce equivalent results.
924 let hash
= compute_hash(&map
, k
);
925 let v
= map
.get(&k
).cloned();
926 let kv
= v
.as_ref().map(|v
| (&k
, v
));
928 assert_eq
!(map
.raw_entry().from_key(&k
), kv
);
929 assert_eq
!(map
.raw_entry().from_hash(hash
, |q
| *q
== k
), kv
);
930 assert_eq
!(map
.raw_entry().from_key_hashed_nocheck(hash
, &k
), kv
);
932 match map
.raw_entry_mut().from_key(&k
) {
933 Occupied(mut o
) => assert_eq
!(Some(o
.get_key_value()), kv
),
934 Vacant(_
) => assert_eq
!(v
, None
),
936 match map
.raw_entry_mut().from_key_hashed_nocheck(hash
, &k
) {
937 Occupied(mut o
) => assert_eq
!(Some(o
.get_key_value()), kv
),
938 Vacant(_
) => assert_eq
!(v
, None
),
940 match map
.raw_entry_mut().from_hash(hash
, |q
| *q
== k
) {
941 Occupied(mut o
) => assert_eq
!(Some(o
.get_key_value()), kv
),
942 Vacant(_
) => assert_eq
!(v
, None
),
947 mod test_drain_filter
{
950 use crate::panic
::{catch_unwind, AssertUnwindSafe}
;
951 use crate::sync
::atomic
::{AtomicUsize, Ordering}
;
953 trait EqSorted
: Iterator
{
954 fn eq_sorted
<I
: IntoIterator
<Item
= Self::Item
>>(self, other
: I
) -> bool
;
957 impl<T
: Iterator
> EqSorted
for T
961 fn eq_sorted
<I
: IntoIterator
<Item
= Self::Item
>>(self, other
: I
) -> bool
{
962 let mut v
: Vec
<_
> = self.collect();
964 v
.into_iter().eq(other
)
970 let mut map
: HashMap
<i32, i32> = HashMap
::new();
971 map
.drain_filter(|_
, _
| unreachable
!("there's nothing to decide on"));
972 assert
!(map
.is_empty());
976 fn consuming_nothing() {
977 let pairs
= (0..3).map(|i
| (i
, i
));
978 let mut map
: HashMap
<_
, _
> = pairs
.collect();
979 assert
!(map
.drain_filter(|_
, _
| false).eq_sorted(crate::iter
::empty()));
980 assert_eq
!(map
.len(), 3);
985 let pairs
= (0..3).map(|i
| (i
, i
));
986 let mut map
: HashMap
<_
, _
> = pairs
.clone().collect();
987 assert
!(map
.drain_filter(|_
, _
| true).eq_sorted(pairs
));
988 assert
!(map
.is_empty());
992 fn mutating_and_keeping() {
993 let pairs
= (0..3).map(|i
| (i
, i
));
994 let mut map
: HashMap
<_
, _
> = pairs
.collect();
996 map
.drain_filter(|_
, v
| {
1000 .eq_sorted(crate::iter
::empty())
1002 assert
!(map
.keys().copied().eq_sorted(0..3));
1003 assert
!(map
.values().copied().eq_sorted(6..9));
1007 fn mutating_and_removing() {
1008 let pairs
= (0..3).map(|i
| (i
, i
));
1009 let mut map
: HashMap
<_
, _
> = pairs
.collect();
1011 map
.drain_filter(|_
, v
| {
1015 .eq_sorted((0..3).map(|i
| (i
, i
+ 6)))
1017 assert
!(map
.is_empty());
1021 fn drop_panic_leak() {
1022 static PREDS
: AtomicUsize
= AtomicUsize
::new(0);
1023 static DROPS
: AtomicUsize
= AtomicUsize
::new(0);
1027 fn drop(&mut self) {
1028 if DROPS
.fetch_add(1, Ordering
::SeqCst
) == 1 {
1029 panic
!("panic in `drop`");
1034 let mut map
= (0..3).map(|i
| (i
, D
)).collect
::<HashMap
<_
, _
>>();
1036 catch_unwind(move || {
1037 drop(map
.drain_filter(|_
, _
| {
1038 PREDS
.fetch_add(1, Ordering
::SeqCst
);
1044 assert_eq
!(PREDS
.load(Ordering
::SeqCst
), 3);
1045 assert_eq
!(DROPS
.load(Ordering
::SeqCst
), 3);
1049 fn pred_panic_leak() {
1050 static PREDS
: AtomicUsize
= AtomicUsize
::new(0);
1051 static DROPS
: AtomicUsize
= AtomicUsize
::new(0);
1055 fn drop(&mut self) {
1056 DROPS
.fetch_add(1, Ordering
::SeqCst
);
1060 let mut map
= (0..3).map(|i
| (i
, D
)).collect
::<HashMap
<_
, _
>>();
1062 catch_unwind(AssertUnwindSafe(|| {
1063 drop(map
.drain_filter(|_
, _
| match PREDS
.fetch_add(1, Ordering
::SeqCst
) {
1070 assert_eq
!(PREDS
.load(Ordering
::SeqCst
), 2);
1071 assert_eq
!(DROPS
.load(Ordering
::SeqCst
), 1);
1072 assert_eq
!(map
.len(), 2);
1075 // Same as above, but attempt to use the iterator again after the panic in the predicate
1077 fn pred_panic_reuse() {
1078 static PREDS
: AtomicUsize
= AtomicUsize
::new(0);
1079 static DROPS
: AtomicUsize
= AtomicUsize
::new(0);
1083 fn drop(&mut self) {
1084 DROPS
.fetch_add(1, Ordering
::SeqCst
);
1088 let mut map
= (0..3).map(|i
| (i
, D
)).collect
::<HashMap
<_
, _
>>();
1091 let mut it
= map
.drain_filter(|_
, _
| match PREDS
.fetch_add(1, Ordering
::SeqCst
) {
1095 catch_unwind(AssertUnwindSafe(|| while it
.next().is_some() {}
)).unwrap_err();
1096 // Iterator behaviour after a panic is explicitly unspecified,
1097 // so this is just the current implementation:
1098 let result
= catch_unwind(AssertUnwindSafe(|| it
.next()));
1099 assert
!(result
.is_err());
1102 assert_eq
!(PREDS
.load(Ordering
::SeqCst
), 3);
1103 assert_eq
!(DROPS
.load(Ordering
::SeqCst
), 1);
1104 assert_eq
!(map
.len(), 2);
1110 let map
= HashMap
::from([(1, 2), (3, 4)]);
1111 let unordered_duplicates
= HashMap
::from([(3, 4), (1, 2), (1, 2)]);
1112 assert_eq
!(map
, unordered_duplicates
);
1114 // This next line must infer the hasher type parameter.
1115 // If you make a change that causes this line to no longer infer,
1116 // that's a problem!
1117 let _must_not_require_type_annotation
= HashMap
::from([(1, 2)]);
1121 fn const_with_hasher() {
1122 const X
: HashMap
<(), (), ()> = HashMap
::with_hasher(());
1123 assert_eq
!(X
.len(), 0);