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)]
|
#[derive(Debug)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
kind: ErrorKind,
|
kind: ErrorKind,
|
||||||
/// Indicates that the `struct` can pretend to own a mutable static reference
|
/// We want this type to be `?UnwindSafe` and `?RefUnwindSafe` - the same as `std::io::Error`.
|
||||||
/// and an [`UnsafeCell`](core::cell::UnsafeCell), which are not unwind safe.
|
///
|
||||||
/// This is so that it does not introduce non-additive cargo features.
|
/// In `std` builds the existence of `dyn std::error:Error` prevents `UnwindSafe` and
|
||||||
_not_unwind_safe: core::marker::PhantomData<(&'static mut (), core::cell::UnsafeCell<()>)>,
|
/// `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")]
|
#[cfg(feature = "std")]
|
||||||
error: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
|
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 {
|
macro_rules! define_errorkind {
|
||||||
($($(#[$($attr:tt)*])* $kind:ident),*) => {
|
($($(#[$($attr:tt)*])* $kind:ident),*) => {
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
#[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).
|
// Types are `Send` and `Sync` where possible (C-SEND-SYNC).
|
||||||
assert_send::<Types>();
|
assert_send::<Types>();
|
||||||
assert_sync::<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