Closed
Description
Since the implementation of Vec::retain
changed after Rust 1.25, items may not be dropped when the predicate panics.
Reproduction example
#[derive(Debug)]
struct Foo(i32);
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropping Foo({})", self.0);
}
}
fn main() {
let mut v = (0..3).map(Foo).collect::<Vec<_>>();
println!("Before retain");
v.retain(|&Foo(n)| match n {
0 => false,
2 => panic!("Boo"),
_ => true,
});
println!("After retain");
}
Expected result
All 3 Foo
instances are dropped. The output should look like (with Rust 1.25):
Before retain
thread 'main' panicked at 'Boo', a.rs:15:14
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Dropping Foo(1)
Dropping Foo(0)
Dropping Foo(2)
Actual result
Only one Foo
instance is dropped. The output since Rust 1.26 (and with 1.27.1) is:
Before retain
Dropping Foo(0)
thread 'main' panicked at 'Boo', a.rs:15:14
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Edited to clarify item leak (i.e. not dropped).