diff --git a/api/io/all-features.txt b/api/io/all-features.txt index 1a6cb4f7a..46b6a2935 100644 --- a/api/io/all-features.txt +++ b/api/io/all-features.txt @@ -1,6 +1,5 @@ #[repr(transparent)] pub struct bitcoin_io::FromStd(_) #[repr(transparent)] pub struct bitcoin_io::ToStd(_) -impl !core::marker::Sync for bitcoin_io::Error impl !core::panic::unwind_safe::RefUnwindSafe for bitcoin_io::Error impl !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Error impl bitcoin_io::BufRead for &[u8] @@ -70,6 +69,7 @@ impl core::marker::Send for bitcoin_io::Error impl core::marker::Send for bitcoin_io::ErrorKind impl core::marker::Send for bitcoin_io::Sink impl core::marker::StructuralPartialEq for bitcoin_io::ErrorKind +impl core::marker::Sync for bitcoin_io::Error impl core::marker::Sync for bitcoin_io::ErrorKind impl core::marker::Sync for bitcoin_io::Sink impl core::marker::Unpin for bitcoin_io::Error diff --git a/api/io/alloc-only.txt b/api/io/alloc-only.txt index e0d9a76e5..5cb612794 100644 --- a/api/io/alloc-only.txt +++ b/api/io/alloc-only.txt @@ -1,4 +1,3 @@ -impl !core::marker::Sync for bitcoin_io::Error impl !core::panic::unwind_safe::RefUnwindSafe for bitcoin_io::Error impl !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Error impl bitcoin_io::BufRead for &[u8] @@ -28,6 +27,7 @@ impl core::marker::Send for bitcoin_io::Error impl core::marker::Send for bitcoin_io::ErrorKind impl core::marker::Send for bitcoin_io::Sink impl core::marker::StructuralPartialEq for bitcoin_io::ErrorKind +impl core::marker::Sync for bitcoin_io::Error impl core::marker::Sync for bitcoin_io::ErrorKind impl core::marker::Sync for bitcoin_io::Sink impl core::marker::Unpin for bitcoin_io::Error diff --git a/api/io/no-features.txt b/api/io/no-features.txt index 3874ee8f7..493aab930 100644 --- a/api/io/no-features.txt +++ b/api/io/no-features.txt @@ -1,4 +1,3 @@ -impl !core::marker::Sync for bitcoin_io::Error impl !core::panic::unwind_safe::RefUnwindSafe for bitcoin_io::Error impl !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Error impl bitcoin_io::BufRead for &[u8] @@ -27,6 +26,7 @@ impl core::marker::Send for bitcoin_io::Error impl core::marker::Send for bitcoin_io::ErrorKind impl core::marker::Send for bitcoin_io::Sink impl core::marker::StructuralPartialEq for bitcoin_io::ErrorKind +impl core::marker::Sync for bitcoin_io::Error impl core::marker::Sync for bitcoin_io::ErrorKind impl core::marker::Sync for bitcoin_io::Sink impl core::marker::Unpin for bitcoin_io::Error diff --git a/io/src/error.rs b/io/src/error.rs index 6ef943e42..ae5b5e44a 100644 --- a/io/src/error.rs +++ b/io/src/error.rs @@ -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, #[cfg(feature = "std")] error: Option>, @@ -100,6 +102,13 @@ impl From 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)] diff --git a/io/tests/api.rs b/io/tests/api.rs index 608969c02..efc64f2e6 100644 --- a/io/tests/api.rs +++ b/io/tests/api.rs @@ -137,4 +137,8 @@ fn all_non_error_tyes_implement_send_sync() { // Types are `Send` and `Sync` where possible (C-SEND-SYNC). assert_send::(); assert_sync::(); + + // Error types are meaningful and well-behaved (C-GOOD-ERR) + assert_send::(); + assert_sync::(); }