about summary refs log tree commit diff
path: root/src/liballoc/collections
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-12-13 04:21:27 +0100
committerGitHub <noreply@github.com>2019-12-13 04:21:27 +0100
commit87f3b16e0b7ebc8d83dc8d57a2013646cb6ebb7b (patch)
tree5c73a530a949af08d7612c8b9a024d9a0637b0c5 /src/liballoc/collections
parent2ca7b7e539b429141028953328ea31db77dbf71a (diff)
parent5e32da184933e4398a99a3be13d21db857f059b5 (diff)
downloadrust-87f3b16e0b7ebc8d83dc8d57a2013646cb6ebb7b.tar.gz
rust-87f3b16e0b7ebc8d83dc8d57a2013646cb6ebb7b.zip
Rollup merge of #67243 - jonas-schievink:linkedlist-drop, r=KodrAus
LinkedList: drop remaining items when drop panics

https://github.com/rust-lang/rust/pull/67235, but for `LinkedList`, which has the same issue.

I've also copied over the other drop-related tests from `VecDeque` since AFAICT `LinkedList` didn't have any.
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 a0c9263673d..6ee22834a46 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -808,7 +808,21 @@ impl<T> LinkedList<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<#[may_dangle] T> Drop for LinkedList<T> {
     fn drop(&mut self) {
-        while let Some(_) = self.pop_front_node() {}
+        struct DropGuard<'a, T>(&'a mut LinkedList<T>);
+
+        impl<'a, T> Drop for DropGuard<'a, T> {
+            fn drop(&mut self) {
+                // Continue the same loop we do below. This only runs when a destructor has
+                // panicked. If another one panics this will abort.
+                while let Some(_) = self.0.pop_front_node() {}
+            }
+        }
+
+        while let Some(node) = self.pop_front_node() {
+            let guard = DropGuard(self);
+            drop(node);
+            mem::forget(guard);
+        }
     }
 }