diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 3f2c965470652..0c51a802faba3 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -238,16 +238,8 @@ pub struct Formatter<'a> { // NB. Argument is essentially an optimized partially applied formatting function, // equivalent to `exists T.(&T, fn(&T, &mut Formatter<'_>) -> Result`. -struct Void { - _priv: (), - /// Erases all oibits, because `Void` erases the type of the object that - /// will be used to produce formatted output. Since we do not know what - /// oibits the real types have (and they can have any or none), we need to - /// take the most conservative approach and forbid all oibits. - /// - /// It was added after #45197 showed that one could share a `!Sync` - /// object across threads by passing it into `format_args!`. - _oibit_remover: PhantomData<*mut dyn Fn()>, +extern "C" { + type Opaque; } /// This struct represents the generic "argument" which is taken by the Xprintf @@ -259,8 +251,8 @@ struct Void { #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] #[doc(hidden)] pub struct ArgumentV1<'a> { - value: &'a Void, - formatter: fn(&Void, &mut Formatter<'_>) -> Result, + value: &'a Opaque, + formatter: fn(&Opaque, &mut Formatter<'_>) -> Result, } impl<'a> ArgumentV1<'a> { diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr index be6e41afaf811..c8439764effc3 100644 --- a/src/test/ui/fmt/send-sync.stderr +++ b/src/test/ui/fmt/send-sync.stderr @@ -1,34 +1,30 @@ -error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely +error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely --> $DIR/send-sync.rs:8:5 | LL | fn send(_: T) {} | ---- ---- required by this bound in `send` ... LL | send(format_args!("{:?}", c)); - | ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely + | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely | - = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)` - = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>` - = note: required because it appears within the type `core::fmt::Void` - = note: required because it appears within the type `&core::fmt::Void` + = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `core::fmt::Opaque` + = note: required because it appears within the type `&core::fmt::Opaque` = note: required because it appears within the type `std::fmt::ArgumentV1<'_>` = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` = note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `std::fmt::Arguments<'_>` -error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely +error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely --> $DIR/send-sync.rs:9:5 | LL | fn sync(_: T) {} | ---- ---- required by this bound in `sync` ... LL | sync(format_args!("{:?}", c)); - | ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely + | ^^^^ `core::fmt::Opaque` cannot be shared between threads safely | - = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)` - = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>` - = note: required because it appears within the type `core::fmt::Void` - = note: required because it appears within the type `&core::fmt::Void` + = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `core::fmt::Opaque` + = note: required because it appears within the type `&core::fmt::Opaque` = note: required because it appears within the type `std::fmt::ArgumentV1<'_>` = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]`