Closed
Description
use std::sync::{Condvar, Mutex};
fn panic_catcher() {
let condvar = Condvar::new();
std::panic::catch_unwind(move || {
let mutex = Mutex::new(());
let guard = mutex.lock().unwrap();
condvar.wait(guard);
});
}
I expected to see this happen: No errors. This code compiles on Linux, as I would expect based on Condvar's documentation.
Instead, this happened: When compiling on Mac OS, I get this error:
error[E0277]: the type `UnsafeCell<libc::unix::bsd::apple::pthread_cond_t>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> src/lib.rs:176:30
|
176 | std::panic::catch_unwind(move || {
| _____------------------------_^
| | |
| | required by a bound introduced by this call
177 | | let mutex = Mutex::new(());
178 | | let guard = mutex.lock().unwrap();
179 | | condvar.wait(guard);
180 | | });
| |_____^ `UnsafeCell<libc::unix::bsd::apple::pthread_cond_t>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
= help: within `std::sys::unix::locks::pthread_condvar::AllocatedCondvar`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<libc::unix::bsd::apple::pthread_cond_t>`
note: required because it appears within the type `AllocatedCondvar`
--> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys/unix/locks/pthread_condvar.rs:12:8
|
12 | struct AllocatedCondvar(UnsafeCell<libc::pthread_cond_t>);
| ^^^^^^^^^^^^^^^^
= note: required for `*mut std::sys::unix::locks::pthread_condvar::AllocatedCondvar` to implement `UnwindSafe`
note: required because it appears within the type `UnsafeCell<*mut AllocatedCondvar>`
--> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/cell.rs:1987:12
|
1987 | pub struct UnsafeCell<T: ?Sized> {
| ^^^^^^^^^^
note: required because it appears within the type `AtomicPtr<AllocatedCondvar>`
--> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/sync/atomic.rs:186:12
|
186 | pub struct AtomicPtr<T> {
| ^^^^^^^^^
note: required because it appears within the type `LazyBox<AllocatedCondvar>`
--> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys_common/lazy_box.rs:13:19
|
13 | pub(crate) struct LazyBox<T: LazyInit> {
| ^^^^^^^
note: required because it appears within the type `Condvar`
--> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys/unix/locks/pthread_condvar.rs:14:12
|
14 | pub struct Condvar {
| ^^^^^^^
note: required because it appears within the type `Condvar`
--> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sync/condvar.rs:107:12
|
107 | pub struct Condvar {
| ^^^^^^^
note: required because it's used within this closure
--> src/lib.rs:176:30
|
176 | std::panic::catch_unwind(move || {
| ^^^^^^^
note: required by a bound in `catch_unwind`
--> /Users/ecton/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:141:40
|
141 | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
| ^^^^^^^^^^ required by this bound in `catch_unwind`
On Linux, this code compiles correctly, and the hosted Rust docs for Convdar document this type as UnwindSafe. I'm filing this issue to ask:
Is the current MacOS implementation not actually UnwindSafe? My workaround for this issue is to wrap Condvar in AssertUnwindwSafe, but I would like to confirm this is actually safe. My personal hope is that these sync primitives are UnwindSafe and that this is a safe workaround.
Meta
rustc --version --verbose
:
rustc 1.74.0 (79e9716c9 2023-11-13)
binary: rustc
commit-hash: 79e9716c980570bfd1f666e3b16ac583f0168962
commit-date: 2023-11-13
host: x86_64-unknown-linux-gnu
release: 1.74.0
LLVM version: 17.0.4