Merge rust-bitcoin/rust-bitcoin#3920: Make `io::Error` `Sync`

11a9dced76 api: Run just check-api (Tobin C. Harding)
31dda6d53d Make io::Error Sync (Tobin C. Harding)

Pull request description:

  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

ACKs for top commit:
  apoelstra:
    ACK 11a9dced766c56d6258af6f43d8691aaf7b2110f; successfully ran local tests

Tree-SHA512: 77c89a32e6d409be9db3a40573b78f69eadf24f2d6d4739510753e339ba30a5e6082d21fef52b44481ff2b60f49c1b31dfe45fa12299f97176ba48853b9487a6
This commit is contained in:
merge-script 2025-01-21 20:40:13 +00:00
commit 39dd3cad20
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
5 changed files with 20 additions and 7 deletions

View File

@ -1,6 +1,5 @@
#[repr(transparent)] pub struct bitcoin_io::FromStd<T>(_) #[repr(transparent)] pub struct bitcoin_io::FromStd<T>(_)
#[repr(transparent)] pub struct bitcoin_io::ToStd<T>(_) #[repr(transparent)] pub struct bitcoin_io::ToStd<T>(_)
impl !core::marker::Sync for bitcoin_io::Error
impl !core::panic::unwind_safe::RefUnwindSafe 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 !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Error
impl bitcoin_io::BufRead for &[u8] 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::ErrorKind
impl core::marker::Send for bitcoin_io::Sink impl core::marker::Send for bitcoin_io::Sink
impl core::marker::StructuralPartialEq for bitcoin_io::ErrorKind 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::ErrorKind
impl core::marker::Sync for bitcoin_io::Sink impl core::marker::Sync for bitcoin_io::Sink
impl core::marker::Unpin for bitcoin_io::Error impl core::marker::Unpin for bitcoin_io::Error

View File

@ -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::RefUnwindSafe for bitcoin_io::Error
impl !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Error impl !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Error
impl bitcoin_io::BufRead for &[u8] 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::ErrorKind
impl core::marker::Send for bitcoin_io::Sink impl core::marker::Send for bitcoin_io::Sink
impl core::marker::StructuralPartialEq for bitcoin_io::ErrorKind 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::ErrorKind
impl core::marker::Sync for bitcoin_io::Sink impl core::marker::Sync for bitcoin_io::Sink
impl core::marker::Unpin for bitcoin_io::Error impl core::marker::Unpin for bitcoin_io::Error

View File

@ -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::RefUnwindSafe for bitcoin_io::Error
impl !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Error impl !core::panic::unwind_safe::UnwindSafe for bitcoin_io::Error
impl bitcoin_io::BufRead for &[u8] 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::ErrorKind
impl core::marker::Send for bitcoin_io::Sink impl core::marker::Send for bitcoin_io::Sink
impl core::marker::StructuralPartialEq for bitcoin_io::ErrorKind 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::ErrorKind
impl core::marker::Sync for bitcoin_io::Sink impl core::marker::Sync for bitcoin_io::Sink
impl core::marker::Unpin for bitcoin_io::Error impl core::marker::Unpin for bitcoin_io::Error

View File

@ -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)]

View File

@ -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>();
} }