Skip to content

Commit 34ef8f5

Browse files
Move to using an extern type for opaqueness
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.
1 parent 6c45e45 commit 34ef8f5

File tree

2 files changed

+12
-24
lines changed

2 files changed

+12
-24
lines changed

Diff for: src/libcore/fmt/mod.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -238,16 +238,8 @@ pub struct Formatter<'a> {
238238
// NB. Argument is essentially an optimized partially applied formatting function,
239239
// equivalent to `exists T.(&T, fn(&T, &mut Formatter<'_>) -> Result`.
240240

241-
struct Void {
242-
_priv: (),
243-
/// Erases all oibits, because `Void` erases the type of the object that
244-
/// will be used to produce formatted output. Since we do not know what
245-
/// oibits the real types have (and they can have any or none), we need to
246-
/// take the most conservative approach and forbid all oibits.
247-
///
248-
/// It was added after #45197 showed that one could share a `!Sync`
249-
/// object across threads by passing it into `format_args!`.
250-
_oibit_remover: PhantomData<*mut dyn Fn()>,
241+
extern "C" {
242+
type Opaque;
251243
}
252244

253245
/// This struct represents the generic "argument" which is taken by the Xprintf
@@ -259,8 +251,8 @@ struct Void {
259251
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
260252
#[doc(hidden)]
261253
pub struct ArgumentV1<'a> {
262-
value: &'a Void,
263-
formatter: fn(&Void, &mut Formatter<'_>) -> Result,
254+
value: &'a Opaque,
255+
formatter: fn(&Opaque, &mut Formatter<'_>) -> Result,
264256
}
265257

266258
impl<'a> ArgumentV1<'a> {

Diff for: src/test/ui/fmt/send-sync.stderr

+8-12
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,30 @@
1-
error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
1+
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
22
--> $DIR/send-sync.rs:8:5
33
|
44
LL | fn send<T: Send>(_: T) {}
55
| ---- ---- required by this bound in `send`
66
...
77
LL | send(format_args!("{:?}", c));
8-
| ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
8+
| ^^^^ `core::fmt::Opaque` cannot be shared between threads safely
99
|
10-
= help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
11-
= note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
12-
= note: required because it appears within the type `core::fmt::Void`
13-
= note: required because it appears within the type `&core::fmt::Void`
10+
= help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `core::fmt::Opaque`
11+
= note: required because it appears within the type `&core::fmt::Opaque`
1412
= note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
1513
= note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]`
1614
= note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]`
1715
= note: required because it appears within the type `std::fmt::Arguments<'_>`
1816

19-
error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
17+
error[E0277]: `core::fmt::Opaque` cannot be shared between threads safely
2018
--> $DIR/send-sync.rs:9:5
2119
|
2220
LL | fn sync<T: Sync>(_: T) {}
2321
| ---- ---- required by this bound in `sync`
2422
...
2523
LL | sync(format_args!("{:?}", c));
26-
| ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
24+
| ^^^^ `core::fmt::Opaque` cannot be shared between threads safely
2725
|
28-
= help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
29-
= note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
30-
= note: required because it appears within the type `core::fmt::Void`
31-
= note: required because it appears within the type `&core::fmt::Void`
26+
= help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `core::fmt::Opaque`
27+
= note: required because it appears within the type `&core::fmt::Opaque`
3228
= note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
3329
= note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]`
3430
= note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]`

0 commit comments

Comments
 (0)