diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2019-12-12 00:14:09 +0100 |
|---|---|---|
| committer | Jonas Schievink <jonasschievink@gmail.com> | 2019-12-12 00:14:09 +0100 |
| commit | 5e32da184933e4398a99a3be13d21db857f059b5 (patch) | |
| tree | 822e5983e1f9e97fda1c02822606ba75a7ed585a /src/liballoc/collections | |
| parent | 27d6f55f47e8875e71083a28ed84ea5a88e1b596 (diff) | |
| download | rust-5e32da184933e4398a99a3be13d21db857f059b5.tar.gz rust-5e32da184933e4398a99a3be13d21db857f059b5.zip | |
LinkedList: drop remaining items when drop panics
Diffstat (limited to 'src/liballoc/collections')
| -rw-r--r-- | src/liballoc/collections/linked_list.rs | 16 |
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); + } } } |
