about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-03-11 14:03:47 +0100
committerGitHub <noreply@github.com>2020-03-11 14:03:47 +0100
commit080d41391d84ccf61b1b3667e731981519f9d5b7 (patch)
tree968d29539ba5e2a488f07bd2207082600a37874b /src/liballoc
parent9674c09ae9b0c520150208bbfd8c66019edbb958 (diff)
parent528cbc4879ceab332d509e4959fcea8baa7e8b92 (diff)
downloadrust-080d41391d84ccf61b1b3667e731981519f9d5b7.tar.gz
rust-080d41391d84ccf61b1b3667e731981519f9d5b7.zip
Rollup merge of #69828 - RalfJung:vec-leak, r=kennytm
fix memory leak when vec::IntoIter panics during drop

Fixes https://github.com/rust-lang/rust/issues/69770
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/vec.rs16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index f661b830428..d1956270f13 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -2626,13 +2626,21 @@ impl<T: Clone> Clone for IntoIter<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<#[may_dangle] T> Drop for IntoIter<T> {
     fn drop(&mut self) {
+        struct DropGuard<'a, T>(&'a mut IntoIter<T>);
+
+        impl<T> Drop for DropGuard<'_, T> {
+            fn drop(&mut self) {
+                // RawVec handles deallocation
+                let _ = unsafe { RawVec::from_raw_parts(self.0.buf.as_ptr(), self.0.cap) };
+            }
+        }
+
+        let guard = DropGuard(self);
         // destroy the remaining elements
         unsafe {
-            ptr::drop_in_place(self.as_mut_slice());
+            ptr::drop_in_place(guard.0.as_mut_slice());
         }
-
-        // RawVec handles deallocation
-        let _ = unsafe { RawVec::from_raw_parts(self.buf.as_ptr(), self.cap) };
+        // now `guard` will be dropped and do the rest
     }
 }