Skip to content

Can UB be triggered by mem::forget of a ScopeGuard? #1

@LunNova

Description

@LunNova

Attempts at guarding a lifetime in this manner typically are unsound as leaking - whether via RC cycles or mem::forget or any other mechanism - can be done in safe code.

use scoped_static::{ScopeGuard, Scoped};

#[tokio::main]
async fn main() {
    let value = Box::new(1.0);
    let ref_value = &value;
    // `guard` ensures no derived "lifted" values exist when dropped
    let guard = ScopeGuard::new(ref_value);
    // `lifted` holds a `'static` reference to `'ref_value`
    let lifted: Scoped<Box<f64>> = guard.lift();
    tokio::spawn(async move {
        // lifted moved here
        let value = **lifted + 1.0;
        assert_eq!(value, 2.0);
        // lifted dropped
    })
    .await
    .unwrap();
   
    std::mem::forget(guard);
}

There have been proposals to add a new auto trait to make this sort of usage safe, called Forget or Leak or Forgettable.

rust-lang/compiler-team#727

rust-lang/rust#120706

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions