Double Drop with #![deny(rust_2024_compatibility)] · Issue #134482 · rust-lang/rust (original) (raw)

I had a custom Rc that was doubly freeing memory because Drop was being called more times than it should.
After a little bit of testing I think this is a small enough Minimal-Reproducible-Example:
playground

// ---------------------------------------- // // If commented, it only calls Drop 2 times // // If not commented, it calls Drop 3 times // // ---------------------------------------- // #![deny(rust_2024_compatibility)]

use std::backtrace::Backtrace;

struct Guard(); impl Clone for Guard { fn clone(&self) -> Self { Self() } } impl Drop for Guard { fn drop(&mut self) { println!("Drop!"); eprintln!("Drop at {}!", Backtrace::force_capture()); } }

fn main() { let _ = method_1(Guard()); }

fn method_1(g: Guard) -> Result<String, ()> { // ----------------------- // // This calls Drop 2 times // // ----------------------- //

// let argument = &g.clone();
// match method_2(argument) {
//     Ok(str) => Ok(str),
//     Err(err) => Err(err),
// }

// --- //

// ----------------------- //
// This calls Drop 3 times //
// ----------------------- //

match method_2(&g.clone()) {
    Ok(str) => Ok(str),
    Err(err) => Err(err),
}

}

fn method_2(_: &Guard) -> Result<String, ()> { panic!("Method 2 panics!"); }

I expected to see this happen: Drop is called twice.

Instead, this happened: Drop is called 3 times.

Notes

enum CustomEnum { MyArm(Vec), }

Meta

rustc --version --verbose:

rustc 1.85.0-nightly (a4cb3c831 2024-12-17)
binary: rustc
commit-hash: a4cb3c831823d9baa56c3d90514b75b2660116fa
commit-date: 2024-12-17
host: x86_64-pc-windows-msvc
release: 1.85.0-nightly
LLVM version: 19.1.5

Backtrace

Reduced stderr from the playground:

     Running `target/debug/playground`
thread 'main' panicked at src/main.rs:51:5:
Method 2 panics!
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Drop at    0: <playground::Guard as core::ops::drop::Drop>::drop
             at ./src/main.rs🔞33
   1: core::ptr::drop_in_place<playground::Guard>
             at ./.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:522:1
   2: playground::method_1
             at ./src/main.rs:46:5
   3: [...]

Drop at    0: <playground::Guard as core::ops::drop::Drop>::drop
             at ./src/main.rs🔞33
   1: core::ptr::drop_in_place<playground::Guard>
             at ./.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:522:1
   2: playground::method_1
             at ./src/main.rs:47:1
   3: [...]

Drop at    0: <playground::Guard as core::ops::drop::Drop>::drop
             at ./src/main.rs🔞33
   1: core::ptr::drop_in_place<playground::Guard>
             at ./.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:522:1
   2: playground::method_1
             at ./src/main.rs:47:1
   3: [...]