@@ -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 >
@@ -2739,6 +2735,7 @@ impl<K, V, A: Allocator + Clone> Drain<'_, K, V, A> {
2739
2735
///
2740
2736
/// assert_eq!(map.len(), 1);
2741
2737
/// ```
2738
+ #[ must_use = "Iterators are lazy unless consumed" ]
2742
2739
pub struct DrainFilter < ' a , K , V , F , A : Allocator + Clone = Global >
2743
2740
where
2744
2741
F : FnMut ( & K , & mut V ) -> bool ,
@@ -2747,30 +2744,6 @@ where
2747
2744
inner : DrainFilterInner < ' a , K , V , A > ,
2748
2745
}
2749
2746
2750
- impl < ' a , K , V , F , A > Drop for DrainFilter < ' a , K , V , F , A >
2751
- where
2752
- F : FnMut ( & K , & mut V ) -> bool ,
2753
- A : Allocator + Clone ,
2754
- {
2755
- #[ cfg_attr( feature = "inline-more" , inline) ]
2756
- fn drop ( & mut self ) {
2757
- while let Some ( item) = self . next ( ) {
2758
- let guard = ConsumeAllOnDrop ( self ) ;
2759
- drop ( item) ;
2760
- mem:: forget ( guard) ;
2761
- }
2762
- }
2763
- }
2764
-
2765
- pub ( super ) struct ConsumeAllOnDrop < ' a , T : Iterator > ( pub & ' a mut T ) ;
2766
-
2767
- impl < T : Iterator > Drop for ConsumeAllOnDrop < ' _ , T > {
2768
- #[ cfg_attr( feature = "inline-more" , inline) ]
2769
- fn drop ( & mut self ) {
2770
- self . 0 . for_each ( drop) ;
2771
- }
2772
- }
2773
-
2774
2747
impl < K , V , F , A > Iterator for DrainFilter < ' _ , K , V , F , A >
2775
2748
where
2776
2749
F : FnMut ( & K , & mut V ) -> bool ,
@@ -8159,7 +8132,7 @@ mod test_map {
8159
8132
}
8160
8133
{
8161
8134
let mut map: HashMap < i32 , i32 > = ( 0 ..8 ) . map ( |x| ( x, x * 10 ) ) . collect ( ) ;
8162
- drop ( map. drain_filter ( |& k, _| k % 2 == 0 ) ) ;
8135
+ map. drain_filter ( |& k, _| k % 2 == 0 ) . for_each ( drop ) ;
8163
8136
assert_eq ! ( map. len( ) , 4 ) ;
8164
8137
}
8165
8138
}
0 commit comments