-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #84662 - dtolnay:unwindsafe, r=Amanieu
Move UnwindSafe, RefUnwindSafe, AssertUnwindSafe to core They were previously only available in std::panic, not core::panic. - https://doc.rust-lang.org/1.51.0/std/panic/trait.UnwindSafe.html - https://doc.rust-lang.org/1.51.0/std/panic/trait.RefUnwindSafe.html - https://doc.rust-lang.org/1.51.0/std/panic/struct.AssertUnwindSafe.html Where this is relevant: trait objects! Inside a `#![no_std]` library it's otherwise impossible to have a struct holding a trait object, and at the same time can be used from downstream std crates in a way that doesn't interfere with catch_unwind. ```rust // common library #![no_std] pub struct Thing { pub(crate) x: &'static (dyn SomeTrait + Send + Sync), } pub(crate) trait SomeTrait {...} ``` ```rust // downstream application fn main() { let thing: library::Thing = ...; let _ = std::panic::catch_unwind(|| { let _ = thing; }); // does not work :( } ``` See https://github.com/dtolnay/colorous/blob/a4131708e2f05d2377964981896ff62dbc9b027b/src/gradient.rs#L7-L15 for a real life example of needing to work around this problem. In particular that workaround would not even be viable if implementors of the trait were provided externally by a caller, as the `feature = "std"` would become non-additive in that case. What happens without the UnwindSafe constraints: ```rust fn main() { let gradient = colorous::VIRIDIS; let _ = std::panic::catch_unwind(|| { let _ = gradient; }); } ``` ```console error[E0277]: the type `(dyn colorous::gradient::EvalGradient + Send + Sync + 'static)` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary --> src/main.rs:3:13 | 3 | let _ = std::panic::catch_unwind(|| { let _ = gradient; }); | ^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn colorous::gradient::EvalGradient + Send + Sync + 'static)` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary | ::: .rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:430:40 | 430 | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> { | ---------- required by this bound in `catch_unwind` | = help: within `Gradient`, the trait `RefUnwindSafe` is not implemented for `(dyn colorous::gradient::EvalGradient + Send + Sync + 'static)` = note: required because it appears within the type `&'static (dyn colorous::gradient::EvalGradient + Send + Sync + 'static)` = note: required because it appears within the type `Gradient` = note: required because of the requirements on the impl of `UnwindSafe` for `&Gradient` = note: required because it appears within the type `[closure@src/main.rs:3:38: 3:62]` ```
- Loading branch information
Showing
7 changed files
with
662 additions
and
638 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.