Make io::Error Sync
Currently we use a marker that contains an `UnsafeCell` but `UnsafeCell` is not `Sync` so this makes `io::Error` not `Sync`. We can instead wrap the `UnsafeCell` and implement `Sync` for it. Fix: #3883
This commit is contained in:
parent
274205e147
commit
31dda6d53d
|
@ -6,10 +6,12 @@ use core::fmt;
|
|||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
kind: ErrorKind,
|
||||
/// Indicates that the `struct` can pretend to own a mutable static reference
|
||||
/// and an [`UnsafeCell`](core::cell::UnsafeCell), which are not unwind safe.
|
||||
/// This is so that it does not introduce non-additive cargo features.
|
||||
_not_unwind_safe: core::marker::PhantomData<(&'static mut (), core::cell::UnsafeCell<()>)>,
|
||||
/// We want this type to be `?UnwindSafe` and `?RefUnwindSafe` - the same as `std::io::Error`.
|
||||
///
|
||||
/// In `std` builds the existence of `dyn std::error:Error` prevents `UnwindSafe` and
|
||||
/// `RefUnwindSafe` from being automatically implemented. But in `no-std` builds without the
|
||||
/// marker nothing prevents it.
|
||||
_not_unwind_safe: core::marker::PhantomData<NotUnwindSafe>,
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
error: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
|
||||
|
@ -100,6 +102,13 @@ impl From<Error> for std::io::Error {
|
|||
}
|
||||
}
|
||||
|
||||
/// Useful for preventing `UnwindSafe` and `RefUnwindSafe` from being automatically implemented.
|
||||
struct NotUnwindSafe {
|
||||
_not_unwind_safe: core::marker::PhantomData<(&'static mut (), core::cell::UnsafeCell<()>)>,
|
||||
}
|
||||
|
||||
unsafe impl Sync for NotUnwindSafe {}
|
||||
|
||||
macro_rules! define_errorkind {
|
||||
($($(#[$($attr:tt)*])* $kind:ident),*) => {
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||
|
|
|
@ -137,4 +137,8 @@ fn all_non_error_tyes_implement_send_sync() {
|
|||
// Types are `Send` and `Sync` where possible (C-SEND-SYNC).
|
||||
assert_send::<Types>();
|
||||
assert_sync::<Types>();
|
||||
|
||||
// Error types are meaningful and well-behaved (C-GOOD-ERR)
|
||||
assert_send::<Errors>();
|
||||
assert_sync::<Errors>();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue