diff options
| author | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2017-10-11 10:57:30 +0200 |
|---|---|---|
| committer | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2017-10-11 13:26:05 +0200 |
| commit | 787f9f4ab762c54ce7125451460b01000a26cfd7 (patch) | |
| tree | e7260ca75325a517c5452096a13f20e5dcc2065c | |
| parent | 264aafe0566e521bbc95bd3f44dae97591c9fd20 (diff) | |
| download | rust-787f9f4ab762c54ce7125451460b01000a26cfd7.tar.gz rust-787f9f4ab762c54ce7125451460b01000a26cfd7.zip | |
Prevent fmt::Arguments from being shared across threads
Fixes #45197
| -rw-r--r-- | src/libcore/fmt/mod.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/fmt/send-sync.rs | 20 | ||||
| -rw-r--r-- | src/test/ui/fmt/send-sync.stderr | 34 |
3 files changed, 55 insertions, 0 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 1e45af5b105..4b263596ac1 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -261,6 +261,7 @@ pub struct Formatter<'a> { struct Void { _priv: (), + _oibit_remover: PhantomData<*mut Fn()>, } /// This struct represents the generic "argument" which is taken by the Xprintf diff --git a/src/test/ui/fmt/send-sync.rs b/src/test/ui/fmt/send-sync.rs new file mode 100644 index 00000000000..bb4f9dfffc7 --- /dev/null +++ b/src/test/ui/fmt/send-sync.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn send<T: Send>(_: T) {} +fn sync<T: Sync>(_: T) {} + +fn main() { + // `Cell` is not `Sync`, so `&Cell` is neither `Sync` nor `Send`, + // `std::fmt::Arguments` used to forget this... + let c = std::cell::Cell::new(42); + send(format_args!("{:?}", c)); + sync(format_args!("{:?}", c)); +} diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr new file mode 100644 index 00000000000..1ec53d220e9 --- /dev/null +++ b/src/test/ui/fmt/send-sync.stderr @@ -0,0 +1,34 @@ +error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `[std::fmt::ArgumentV1<'_>]` + --> $DIR/send-sync.rs:18:5 + | +18 | send(format_args!("{:?}", c)); + | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely + | + = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static` + = note: required because it appears within the type `std::marker::PhantomData<*mut 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` + = 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<'_>` + = note: required by `send` + +error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>` + --> $DIR/send-sync.rs:19:5 + | +19 | sync(format_args!("{:?}", c)); + | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely + | + = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static` + = note: required because it appears within the type `std::marker::PhantomData<*mut 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` + = 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<'_>]` + = note: required because it appears within the type `std::fmt::Arguments<'_>` + = note: required by `sync` + +error: aborting due to 2 previous errors + |
