]> git.lizzy.rs Git - rust.git/commitdiff
Move to using an extern type for opaqueness
authorMark Rousskov <mark.simulacrum@gmail.com>
Sat, 15 Feb 2020 23:47:34 +0000 (18:47 -0500)
committerMark Rousskov <mark.simulacrum@gmail.com>
Mon, 17 Feb 2020 14:18:33 +0000 (09:18 -0500)
This prevents accidental dereferences and so forth of the Void type, as well as
cleaning up the error message to reference Opaque rather than the more
complicated PhantomData type.

src/libcore/fmt/mod.rs
src/test/ui/fmt/send-sync.stderr

index 3f2c965470652137410d250a9f385c197da62514..0c51a802faba38cef6765c5f2fe0d7c3cdcc8ef1 100644 (file)
@@ -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> {
index be6e41afaf81169788ad66b7aae26c18d739c36a..c8439764effc331dfbd3d2a2a076da8fccdda4fb 100644 (file)
@@ -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: 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: 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<'_>]`