Skip to content

Latest commit

 

History

History
71 lines (50 loc) · 3.64 KB

3260-deprecate-unwindsafe.md

File metadata and controls

71 lines (50 loc) · 3.64 KB

Summary

Currently rust has the UnwindSafe and RefUnwindSafe marker traits. This RFC proposes to deprecate them, and remove the F: UnwindSafe bound on catch_unwind.

Motivation

Unwind safety is not actually related to safety. It acts as a lint. AssertUnwindSafe can be used to ignore it, and using it does not require unsafe. If using it results in undefined behaviour or unsoundness, the problem lies elsewhere. The existence of unwind safety makes it seem as if you can rely on it for soundness, which is not true (See discussion in UnwindSafe docs are unclear.)

It can also be problematic when a type does not implement the marker trait, but it could, notably with trait objects (See discussion in UnwindSafe is unergonomic). It can also be a pain point for library authors, who are not sure if they should add a bound on them for their generic types to guarantee their types are UnwindSafe, which would make their downstream users sometimes have to use AssertUnwindSafe despite not using catch_unwind just to satisfy the bounds.

Guide-level explanation

UnwindSafe and RefUnwindSafe are deprecated, and you never need to use them. If you can cause undefined behaviour with catch_unwind, something else is unsound.

The following now compiles:

    let x = std::cell::UnsafeCell::new(1u8);
    let result = std::panic::catch_unwind(|| {
        println!("{:p}", x.get());
        panic!()
    });

Which used to require AssertUnwindSafe:

    let x = std::panic::AssertUnwindSafe(std::cell::UnsafeCell::new(1u8));
    let result = std::panic::catch_unwind(|| {
        println!("{:p}", x.get());
        panic!()
    });

Reference-level explanation

UnwindSafe and RefUnwindSafe are now deprecated, and the UnwindSafe bound on the F generic parameter of catch_unwind is removed.

Drawbacks

We lose any value that UnwindSafe was actually providing as a lint.

Rationale and alternatives

  • We could keep UnwindSafe as-is without deprecating it.
  • Rename UnwindSafe to something that does not mention "safety".
  • We could make using something !UnwindSafe through catch_unwind a warning via language magic instead of completely removing it. This would probably require a fundamentally new feature of trait resolution, to turn a missing trait implementation into a warning.

Prior art

In the pull request where UnwindSafe was moved to core, it was mentioned the libs team may want to deprecate it rust-lang/rust#84662 (comment)

I found a comment in this issue mentioning deprecation as far back as 2019: rust-lang/rust#40628 (comment)

Unresolved questions

  • How will this impact the ecosystem? How will libraries with an MSRV deal with this?

Future possibilities