diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 7757068a4f2b9..f74e563f1b9c0 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -298,3 +298,7 @@ impl const From for OnceCell { OnceCell { inner: UnsafeCell::new(Some(value)) } } } + +// Just like for `Cell` this isn't needed, but results in nicer error messages. +#[unstable(feature = "once_cell", issue = "74465")] +impl !Sync for OnceCell {} diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 1326fc9ab096f..74055602ec2e6 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -469,6 +469,62 @@ pub macro Copy($item:item) { #[cfg_attr(not(test), rustc_diagnostic_item = "Sync")] #[lang = "sync"] #[rustc_on_unimplemented( + on( + _Self = "std::cell::OnceCell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead" + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU16` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU32` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU64` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicUsize` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI8` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI16` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI64` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicIsize` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead", + ), + on( + _Self = "std::cell::Cell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`", + ), + on( + _Self = "std::cell::RefCell", + note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead", + ), message = "`{Self}` cannot be shared between threads safely", label = "`{Self}` cannot be shared between threads safely" )] diff --git a/tests/ui/async-await/issue-68112.drop_tracking.stderr b/tests/ui/async-await/issue-68112.drop_tracking.stderr index f2802698fd5b6..bd648de30672d 100644 --- a/tests/ui/async-await/issue-68112.drop_tracking.stderr +++ b/tests/ui/async-await/issue-68112.drop_tracking.stderr @@ -5,6 +5,7 @@ LL | require_send(send_fut); | ^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead note: future is not `Send` as it awaits another future which is not `Send` --> $DIR/issue-68112.rs:34:17 | @@ -23,6 +24,7 @@ LL | require_send(send_fut); | ^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead note: future is not `Send` as it awaits another future which is not `Send` --> $DIR/issue-68112.rs:43:17 | @@ -43,6 +45,7 @@ LL | require_send(send_fut); | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead = note: required for `Arc>` to implement `Send` note: required because it's used within this `async fn` body --> $DIR/issue-68112.rs:50:31 diff --git a/tests/ui/async-await/issue-68112.no_drop_tracking.stderr b/tests/ui/async-await/issue-68112.no_drop_tracking.stderr index 38eb85b302fd5..35b7341f63a4d 100644 --- a/tests/ui/async-await/issue-68112.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-68112.no_drop_tracking.stderr @@ -5,6 +5,7 @@ LL | require_send(send_fut); | ^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead note: future is not `Send` as it awaits another future which is not `Send` --> $DIR/issue-68112.rs:34:17 | @@ -23,6 +24,7 @@ LL | require_send(send_fut); | ^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead note: future is not `Send` as it awaits another future which is not `Send` --> $DIR/issue-68112.rs:43:17 | @@ -43,6 +45,7 @@ LL | require_send(send_fut); | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead = note: required for `Arc>` to implement `Send` note: required because it's used within this `async fn` body --> $DIR/issue-68112.rs:50:31 diff --git a/tests/ui/generator/issue-68112.rs b/tests/ui/generator/issue-68112.rs index 21026f45cb823..9def544e3d25c 100644 --- a/tests/ui/generator/issue-68112.rs +++ b/tests/ui/generator/issue-68112.rs @@ -40,6 +40,7 @@ fn test1() { require_send(send_gen); //~^ ERROR generator cannot be sent between threads //~| NOTE not `Send` + //~| NOTE use `std::sync::RwLock` instead } pub fn make_gen2(t: T) -> impl Generator { @@ -66,6 +67,7 @@ fn test2() { //~| NOTE required for //~| NOTE required by a bound introduced by this call //~| NOTE captures the following types + //~| NOTE use `std::sync::RwLock` instead } fn main() {} diff --git a/tests/ui/generator/issue-68112.stderr b/tests/ui/generator/issue-68112.stderr index eb99d42c92068..b42bc93d01f66 100644 --- a/tests/ui/generator/issue-68112.stderr +++ b/tests/ui/generator/issue-68112.stderr @@ -5,6 +5,7 @@ LL | require_send(send_gen); | ^^^^^^^^ generator is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead note: generator is not `Send` as this value is used across a yield --> $DIR/issue-68112.rs:36:9 | @@ -23,7 +24,7 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error[E0277]: `RefCell` cannot be shared between threads safely - --> $DIR/issue-68112.rs:63:18 + --> $DIR/issue-68112.rs:64:18 | LL | require_send(send_gen); | ------------ ^^^^^^^^ `RefCell` cannot be shared between threads safely @@ -31,25 +32,26 @@ LL | require_send(send_gen); | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead = note: required for `Arc>` to implement `Send` note: required because it's used within this generator - --> $DIR/issue-68112.rs:48:5 + --> $DIR/issue-68112.rs:49:5 | LL | || { | ^^ note: required because it appears within the type `impl Generator>>` - --> $DIR/issue-68112.rs:45:30 + --> $DIR/issue-68112.rs:46:30 | LL | pub fn make_gen2(t: T) -> impl Generator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required because it appears within the type `impl Generator>>` - --> $DIR/issue-68112.rs:53:34 + --> $DIR/issue-68112.rs:54:34 | LL | fn make_non_send_generator2() -> impl Generator>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: required because it captures the following types: `impl Generator>>`, `()` note: required because it's used within this generator - --> $DIR/issue-68112.rs:59:20 + --> $DIR/issue-68112.rs:60:20 | LL | let send_gen = || { | ^^ diff --git a/tests/ui/generator/not-send-sync.stderr b/tests/ui/generator/not-send-sync.stderr index a821c57b923a0..1711df729b8c0 100644 --- a/tests/ui/generator/not-send-sync.stderr +++ b/tests/ui/generator/not-send-sync.stderr @@ -12,6 +12,7 @@ LL | | }); | |_____^ `Cell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead = note: required for `&Cell` to implement `Send` note: required because it's used within this generator --> $DIR/not-send-sync.rs:16:17 @@ -36,6 +37,7 @@ LL | | }); | |_____^ generator is not `Sync` | = help: within `[generator@$DIR/not-send-sync.rs:9:17: 9:19]`, the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead note: generator is not `Sync` as this value is used across a yield --> $DIR/not-send-sync.rs:12:9 | diff --git a/tests/ui/generator/print/generator-print-verbose-1.stderr b/tests/ui/generator/print/generator-print-verbose-1.stderr index ebf35be581c60..45d018b8ebad5 100644 --- a/tests/ui/generator/print/generator-print-verbose-1.stderr +++ b/tests/ui/generator/print/generator-print-verbose-1.stderr @@ -5,6 +5,7 @@ LL | require_send(send_gen); | ^^^^^^^^ generator is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead note: generator is not `Send` as this value is used across a yield --> $DIR/generator-print-verbose-1.rs:35:9 | @@ -29,6 +30,7 @@ LL | require_send(send_gen); | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead = note: required for `Arc>` to implement `Send` note: required because it's used within this generator --> $DIR/generator-print-verbose-1.rs:42:5 diff --git a/tests/ui/generator/print/generator-print-verbose-2.stderr b/tests/ui/generator/print/generator-print-verbose-2.stderr index 909e49c38b8d1..59112ce0a79e6 100644 --- a/tests/ui/generator/print/generator-print-verbose-2.stderr +++ b/tests/ui/generator/print/generator-print-verbose-2.stderr @@ -12,6 +12,7 @@ LL | | }); | |_____^ `Cell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead = note: required for `&'_#4r Cell` to implement `Send` note: required because it's used within this generator --> $DIR/generator-print-verbose-2.rs:19:17 @@ -36,6 +37,7 @@ LL | | }); | |_____^ generator is not `Sync` | = help: within `[main::{closure#0} upvar_tys=() {Cell, ()}]`, the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead note: generator is not `Sync` as this value is used across a yield --> $DIR/generator-print-verbose-2.rs:15:9 | diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr index 5dc8c2b607e61..aee73380f15e7 100644 --- a/tests/ui/issues/issue-7364.stderr +++ b/tests/ui/issues/issue-7364.stderr @@ -5,6 +5,7 @@ LL | static boxed: Box> = Box::new(RefCell::new(0)); | ^^^^^^^^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead = note: required for `Unique>` to implement `Sync` = note: required because it appears within the type `Box>` = note: shared static variables must have a type that implements `Sync` diff --git a/tests/ui/stdlib-unit-tests/not-sync.stderr b/tests/ui/stdlib-unit-tests/not-sync.stderr index 1ee358ba8368e..4e34e10e37789 100644 --- a/tests/ui/stdlib-unit-tests/not-sync.stderr +++ b/tests/ui/stdlib-unit-tests/not-sync.stderr @@ -5,6 +5,7 @@ LL | test::>(); | ^^^^^^^^^ `Cell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead note: required by a bound in `test` --> $DIR/not-sync.rs:5:12 | @@ -18,6 +19,7 @@ LL | test::>(); | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `RefCell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead note: required by a bound in `test` --> $DIR/not-sync.rs:5:12 | diff --git a/tests/ui/mutexguard-sync.rs b/tests/ui/sync/mutexguard-sync.rs similarity index 100% rename from tests/ui/mutexguard-sync.rs rename to tests/ui/sync/mutexguard-sync.rs diff --git a/tests/ui/mutexguard-sync.stderr b/tests/ui/sync/mutexguard-sync.stderr similarity index 83% rename from tests/ui/mutexguard-sync.stderr rename to tests/ui/sync/mutexguard-sync.stderr index 3fbb2ddf183d3..4dc5571196c14 100644 --- a/tests/ui/mutexguard-sync.stderr +++ b/tests/ui/sync/mutexguard-sync.stderr @@ -7,6 +7,7 @@ LL | test_sync(guard); | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead = note: required for `MutexGuard<'_, Cell>` to implement `Sync` note: required by a bound in `test_sync` --> $DIR/mutexguard-sync.rs:5:17 diff --git a/tests/ui/sync/suggest-cell.rs b/tests/ui/sync/suggest-cell.rs new file mode 100644 index 0000000000000..3284eae7be181 --- /dev/null +++ b/tests/ui/sync/suggest-cell.rs @@ -0,0 +1,31 @@ +fn require_sync() {} +//~^ NOTE required by this bound in `require_sync` +//~| NOTE required by this bound in `require_sync` +//~| NOTE required by this bound in `require_sync` +//~| NOTE required by this bound in `require_sync` +//~| NOTE required by a bound in `require_sync` +//~| NOTE required by a bound in `require_sync` +//~| NOTE required by a bound in `require_sync` +//~| NOTE required by a bound in `require_sync` + +fn main() { + require_sync::>(); + //~^ ERROR `Cell<()>` cannot be shared between threads safely + //~| NOTE `Cell<()>` cannot be shared between threads safely + //~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` + + require_sync::>(); + //~^ ERROR `Cell` cannot be shared between threads safely + //~| NOTE `Cell` cannot be shared between threads safely + //~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead + + require_sync::>(); + //~^ ERROR `Cell` cannot be shared between threads safely + //~| NOTE `Cell` cannot be shared between threads safely + //~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead + + require_sync::>(); + //~^ ERROR `Cell` cannot be shared between threads safely + //~| NOTE `Cell` cannot be shared between threads safely + //~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead +} diff --git a/tests/ui/sync/suggest-cell.stderr b/tests/ui/sync/suggest-cell.stderr new file mode 100644 index 0000000000000..c232c1ccd53dd --- /dev/null +++ b/tests/ui/sync/suggest-cell.stderr @@ -0,0 +1,59 @@ +error[E0277]: `Cell<()>` cannot be shared between threads safely + --> $DIR/suggest-cell.rs:12:20 + | +LL | require_sync::>(); + | ^^^^^^^^^^^^^^^^^^^ `Cell<()>` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `Cell<()>` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` +note: required by a bound in `require_sync` + --> $DIR/suggest-cell.rs:1:20 + | +LL | fn require_sync() {} + | ^^^^ required by this bound in `require_sync` + +error[E0277]: `Cell` cannot be shared between threads safely + --> $DIR/suggest-cell.rs:17:20 + | +LL | require_sync::>(); + | ^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead +note: required by a bound in `require_sync` + --> $DIR/suggest-cell.rs:1:20 + | +LL | fn require_sync() {} + | ^^^^ required by this bound in `require_sync` + +error[E0277]: `Cell` cannot be shared between threads safely + --> $DIR/suggest-cell.rs:22:20 + | +LL | require_sync::>(); + | ^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead +note: required by a bound in `require_sync` + --> $DIR/suggest-cell.rs:1:20 + | +LL | fn require_sync() {} + | ^^^^ required by this bound in `require_sync` + +error[E0277]: `Cell` cannot be shared between threads safely + --> $DIR/suggest-cell.rs:27:20 + | +LL | require_sync::>(); + | ^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead +note: required by a bound in `require_sync` + --> $DIR/suggest-cell.rs:1:20 + | +LL | fn require_sync() {} + | ^^^^ required by this bound in `require_sync` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sync/suggest-once-cell.rs b/tests/ui/sync/suggest-once-cell.rs new file mode 100644 index 0000000000000..82fca45b1a47f --- /dev/null +++ b/tests/ui/sync/suggest-once-cell.rs @@ -0,0 +1,12 @@ +#![feature(once_cell)] + +fn require_sync() {} +//~^ NOTE required by this bound in `require_sync` +//~| NOTE required by a bound in `require_sync` + +fn main() { + require_sync::>(); + //~^ ERROR `OnceCell<()>` cannot be shared between threads safely + //~| NOTE `OnceCell<()>` cannot be shared between threads safely + //~| NOTE use `std::sync::OnceLock` instead +} diff --git a/tests/ui/sync/suggest-once-cell.stderr b/tests/ui/sync/suggest-once-cell.stderr new file mode 100644 index 0000000000000..fadf05374d8ca --- /dev/null +++ b/tests/ui/sync/suggest-once-cell.stderr @@ -0,0 +1,17 @@ +error[E0277]: `OnceCell<()>` cannot be shared between threads safely + --> $DIR/suggest-once-cell.rs:8:20 + | +LL | require_sync::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^ `OnceCell<()>` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `OnceCell<()>` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead +note: required by a bound in `require_sync` + --> $DIR/suggest-once-cell.rs:3:20 + | +LL | fn require_sync() {} + | ^^^^ required by this bound in `require_sync` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sync/suggest-ref-cell.rs b/tests/ui/sync/suggest-ref-cell.rs new file mode 100644 index 0000000000000..6b972ae09622e --- /dev/null +++ b/tests/ui/sync/suggest-ref-cell.rs @@ -0,0 +1,12 @@ +#![feature(once_cell)] + +fn require_sync() {} +//~^ NOTE required by this bound in `require_sync` +//~| NOTE required by a bound in `require_sync` + +fn main() { + require_sync::>(); + //~^ ERROR `RefCell<()>` cannot be shared between threads safely + //~| NOTE `RefCell<()>` cannot be shared between threads safely + //~| NOTE use `std::sync::RwLock` instead +} diff --git a/tests/ui/sync/suggest-ref-cell.stderr b/tests/ui/sync/suggest-ref-cell.stderr new file mode 100644 index 0000000000000..9e8b8fcb42ed0 --- /dev/null +++ b/tests/ui/sync/suggest-ref-cell.stderr @@ -0,0 +1,17 @@ +error[E0277]: `RefCell<()>` cannot be shared between threads safely + --> $DIR/suggest-ref-cell.rs:8:20 + | +LL | require_sync::>(); + | ^^^^^^^^^^^^^^^^^^^^^^ `RefCell<()>` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `RefCell<()>` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead +note: required by a bound in `require_sync` + --> $DIR/suggest-ref-cell.rs:3:20 + | +LL | fn require_sync() {} + | ^^^^ required by this bound in `require_sync` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.