@@ -975,12 +975,9 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
975
975
/// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of
976
976
/// whether you choose to keep or remove it.
977
977
///
978
- /// When the returned DrainedFilter is dropped, any remaining elements that satisfy
979
- /// the predicate are dropped from the table.
980
- ///
981
- /// It is unspecified how many more elements will be subjected to the closure
982
- /// if a panic occurs in the closure, or a panic occurs while dropping an element,
983
- /// or if the `DrainFilter` value is leaked.
978
+ /// If the returned `DrainFilter` is not exhausted, e.g. because it is dropped without iterating
979
+ /// or the iteration short-circuits, then the remaining elements will be retained.
980
+ /// Use [`retain()`] with a negated predicate if you do not need the returned iterator.
984
981
///
985
982
/// Keeps the allocated memory for reuse.
986
983
///
@@ -1007,9 +1004,8 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
1007
1004
/// let d = map.drain_filter(|k, _v| k % 2 != 0);
1008
1005
/// }
1009
1006
///
1010
- /// // But the map lens have been reduced by half
1011
- /// // even if we do not use DrainFilter iterator.
1012
- /// assert_eq!(map.len(), 4);
1007
+ /// // DrainFilter was not exhausted, therefore no elements were drained.
1008
+ /// assert_eq!(map.len(), 8);
1013
1009
/// ```
1014
1010
#[ cfg_attr( feature = "inline-more" , inline) ]
1015
1011
pub fn drain_filter < F > ( & mut self , f : F ) -> DrainFilter < ' _ , K , V , F , A >
@@ -2760,6 +2756,7 @@ impl<K, V, A: Allocator + Clone> Drain<'_, K, V, A> {
2760
2756
///
2761
2757
/// assert_eq!(map.len(), 1);
2762
2758
/// ```
2759
+ #[ must_use = "Iterators are lazy unless consumed" ]
2763
2760
pub struct DrainFilter < ' a , K , V , F , A : Allocator + Clone = Global >
2764
2761
where
2765
2762
F : FnMut ( & K , & mut V ) -> bool ,
@@ -2768,30 +2765,6 @@ where
2768
2765
inner : DrainFilterInner < ' a , K , V , A > ,
2769
2766
}
2770
2767
2771
- impl < ' a , K , V , F , A > Drop for DrainFilter < ' a , K , V , F , A >
2772
- where
2773
- F : FnMut ( & K , & mut V ) -> bool ,
2774
- A : Allocator + Clone ,
2775
- {
2776
- #[ cfg_attr( feature = "inline-more" , inline) ]
2777
- fn drop ( & mut self ) {
2778
- while let Some ( item) = self . next ( ) {
2779
- let guard = ConsumeAllOnDrop ( self ) ;
2780
- drop ( item) ;
2781
- mem:: forget ( guard) ;
2782
- }
2783
- }
2784
- }
2785
-
2786
- pub ( super ) struct ConsumeAllOnDrop < ' a , T : Iterator > ( pub & ' a mut T ) ;
2787
-
2788
- impl < T : Iterator > Drop for ConsumeAllOnDrop < ' _ , T > {
2789
- #[ cfg_attr( feature = "inline-more" , inline) ]
2790
- fn drop ( & mut self ) {
2791
- self . 0 . for_each ( drop) ;
2792
- }
2793
- }
2794
-
2795
2768
impl < K , V , F , A > Iterator for DrainFilter < ' _ , K , V , F , A >
2796
2769
where
2797
2770
F : FnMut ( & K , & mut V ) -> bool ,
@@ -8180,7 +8153,7 @@ mod test_map {
8180
8153
}
8181
8154
{
8182
8155
let mut map: HashMap < i32 , i32 > = ( 0 ..8 ) . map ( |x| ( x, x * 10 ) ) . collect ( ) ;
8183
- drop ( map. drain_filter ( |& k, _| k % 2 == 0 ) ) ;
8156
+ map. drain_filter ( |& k, _| k % 2 == 0 ) . for_each ( drop ) ;
8184
8157
assert_eq ! ( map. len( ) , 4 ) ;
8185
8158
}
8186
8159
}
0 commit comments