Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 163ed23

Browse files
Fix leak in vec::IntoIter when a destructor panics
1 parent b04ca13 commit 163ed23

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

src/liballoc/tests/vec.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,35 @@ fn test_into_iter_clone() {
765765
assert_eq!(it.next(), None);
766766
}
767767

768+
#[test]
769+
fn test_into_iter_leak() {
770+
static mut DROPS: i32 = 0;
771+
772+
struct D(bool);
773+
774+
impl Drop for D {
775+
fn drop(&mut self) {
776+
unsafe {
777+
DROPS += 1;
778+
}
779+
780+
if self.0 {
781+
panic!("panic in `drop`");
782+
}
783+
}
784+
}
785+
786+
let v = vec![
787+
D(false),
788+
D(true),
789+
D(false),
790+
];
791+
792+
catch_unwind(move || drop(v.into_iter())).ok();
793+
794+
assert_eq!(unsafe { DROPS }, 3);
795+
}
796+
768797
#[test]
769798
fn test_cow_from() {
770799
let borrowed: &[_] = &["borrowed", "(slice)"];

src/liballoc/vec.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2620,7 +2620,9 @@ impl<T: Clone> Clone for IntoIter<T> {
26202620
unsafe impl<#[may_dangle] T> Drop for IntoIter<T> {
26212621
fn drop(&mut self) {
26222622
// destroy the remaining elements
2623-
for _x in self.by_ref() {}
2623+
unsafe {
2624+
ptr::drop_in_place(self.as_mut_slice());
2625+
}
26242626

26252627
// RawVec handles deallocation
26262628
let _ = unsafe { RawVec::from_raw_parts(self.buf.as_ptr(), self.cap) };

0 commit comments

Comments
 (0)