about summary refs log tree commit diff
path: root/src/liballoc/collections
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2019-12-14 00:55:06 +0100
committerJonas Schievink <jonasschievink@gmail.com>2020-01-19 20:24:36 +0100
commit0ae16b47ffee866ee49f909ea213a28d8068cf56 (patch)
treebbc88dd073366bc4f1cab9f88f3aec0ce4c2430e /src/liballoc/collections
parent163ed23f0081d7283ccaef39141bc29879260663 (diff)
downloadrust-0ae16b47ffee866ee49f909ea213a28d8068cf56.tar.gz
rust-0ae16b47ffee866ee49f909ea213a28d8068cf56.zip
Avoid leak in DrainFilter when a drop panics
Diffstat (limited to 'src/liballoc/collections')
-rw-r--r--src/liballoc/collections/linked_list.rs16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index b88ca8a0fb0..463ec67d668 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -1565,7 +1565,21 @@ where
     F: FnMut(&mut T) -> bool,
 {
     fn drop(&mut self) {
-        self.for_each(drop);
+        struct DropGuard<'r, 'a, T, F>(&'r mut DrainFilter<'a, T, F>)
+            where F: FnMut(&mut T) -> bool;
+
+        impl<'r, 'a, T, F> Drop for DropGuard<'r, 'a, T, F>
+        where F: FnMut(&mut T) -> bool {
+            fn drop(&mut self) {
+                self.0.for_each(drop);
+            }
+        }
+
+        while let Some(item) = self.next() {
+            let guard = DropGuard(self);
+            drop(item);
+            mem::forget(guard);
+        }
     }
 }