about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2023-01-16 18:51:31 +0100
committerNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2023-01-19 21:09:25 +0100
commit6d0c91fda35f7a78ff688ea623d1d2ee9b16cad7 (patch)
treef868ff16dcb7efb2b48e6ddce38e712b14625e46
parente1f630f23de2cbce1870e4a226fa0cb8312f106c (diff)
downloadrust-6d0c91fda35f7a78ff688ea623d1d2ee9b16cad7.tar.gz
rust-6d0c91fda35f7a78ff688ea623d1d2ee9b16cad7.zip
Add `rustc_on_unimplemented` on `Sync` for cell types
Suggest using a lock instead.
-rw-r--r--library/core/src/marker.rs56
-rw-r--r--tests/ui/async-await/issue-68112.drop_tracking.stderr3
-rw-r--r--tests/ui/async-await/issue-68112.no_drop_tracking.stderr3
-rw-r--r--tests/ui/generator/issue-68112.rs2
-rw-r--r--tests/ui/generator/issue-68112.stderr12
-rw-r--r--tests/ui/generator/not-send-sync.stderr2
-rw-r--r--tests/ui/generator/print/generator-print-verbose-1.stderr2
-rw-r--r--tests/ui/generator/print/generator-print-verbose-2.stderr2
-rw-r--r--tests/ui/issues/issue-7364.stderr1
-rw-r--r--tests/ui/stdlib-unit-tests/not-sync.stderr2
-rw-r--r--tests/ui/sync/mutexguard-sync.rs (renamed from tests/ui/mutexguard-sync.rs)0
-rw-r--r--tests/ui/sync/mutexguard-sync.stderr (renamed from tests/ui/mutexguard-sync.stderr)1
-rw-r--r--tests/ui/sync/suggest-cell.rs31
-rw-r--r--tests/ui/sync/suggest-cell.stderr59
-rw-r--r--tests/ui/sync/suggest-once-cell.rs12
-rw-r--r--tests/ui/sync/suggest-once-cell.stderr17
-rw-r--r--tests/ui/sync/suggest-ref-cell.rs12
-rw-r--r--tests/ui/sync/suggest-ref-cell.stderr17
18 files changed, 229 insertions, 5 deletions
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 1326fc9ab09..74055602ec2 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<T>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead"
+    ),
+    on(
+        _Self = "std::cell::Cell<u8>",
+        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<u16>",
+        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<u32>",
+        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<u64>",
+        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<usize>",
+        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<i8>",
+        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<i16>",
+        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<i32>",
+        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<i64>",
+        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<isize>",
+        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<bool>",
+        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<T>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`",
+    ),
+    on(
+        _Self = "std::cell::RefCell<T>",
+        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 f2802698fd5..bd648de3067 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<i32>`
+   = 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<i32>`
+   = 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<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` 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 38eb85b302f..35b7341f63a 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<i32>`
+   = 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<i32>`
+   = 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<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` 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 21026f45cb8..9def544e3d2 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: T) -> impl Generator<Return = T> {
@@ -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 eb99d42c920..b42bc93d01f 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<i32>`
+   = 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<i32>` cannot be shared between threads safely
-  --> $DIR/issue-68112.rs:63:18
+  --> $DIR/issue-68112.rs:64:18
    |
 LL |     require_send(send_gen);
    |     ------------ ^^^^^^^^ `RefCell<i32>` 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<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` 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<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:45:30
+  --> $DIR/issue-68112.rs:46:30
    |
 LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:53:34
+  --> $DIR/issue-68112.rs:54:34
    |
 LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: required because it captures the following types: `impl Generator<Return = Arc<RefCell<i32>>>`, `()`
 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 a821c57b923..1711df729b8 100644
--- a/tests/ui/generator/not-send-sync.stderr
+++ b/tests/ui/generator/not-send-sync.stderr
@@ -12,6 +12,7 @@ LL | |     });
    | |_____^ `Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
+   = 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<i32>` 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<i32>`
+   = 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 ebf35be581c..45d018b8eba 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<i32>`
+   = 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<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` 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 909e49c38b8..59112ce0a79 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<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
+   = 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<i32>` 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<i32>, ()}]`, the trait `Sync` is not implemented for `Cell<i32>`
+   = 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 5dc8c2b607e..aee73380f15 100644
--- a/tests/ui/issues/issue-7364.stderr
+++ b/tests/ui/issues/issue-7364.stderr
@@ -5,6 +5,7 @@ LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
    |               ^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<isize>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Unique<RefCell<isize>>` to implement `Sync`
    = note: required because it appears within the type `Box<RefCell<isize>>`
    = 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 1ee358ba836..4e34e10e377 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<i32>>();
    |            ^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
+   = 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<i32>>();
    |            ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = 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
index b5641838318..b5641838318 100644
--- a/tests/ui/mutexguard-sync.rs
+++ b/tests/ui/sync/mutexguard-sync.rs
diff --git a/tests/ui/mutexguard-sync.stderr b/tests/ui/sync/mutexguard-sync.stderr
index 3fbb2ddf183..4dc5571196c 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<i32>`
+   = 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<i32>>` 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 00000000000..3284eae7be1
--- /dev/null
+++ b/tests/ui/sync/suggest-cell.rs
@@ -0,0 +1,31 @@
+fn require_sync<T: 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::<std::cell::Cell<()>>();
+    //~^ 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::<std::cell::Cell<u8>>();
+    //~^ ERROR `Cell<u8>` cannot be shared between threads safely
+    //~| NOTE `Cell<u8>` 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::<std::cell::Cell<i32>>();
+    //~^ ERROR `Cell<i32>` cannot be shared between threads safely
+    //~| NOTE `Cell<i32>` 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::<std::cell::Cell<bool>>();
+    //~^ ERROR `Cell<bool>` cannot be shared between threads safely
+    //~| NOTE `Cell<bool>` 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 00000000000..c232c1ccd53
--- /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::<std::cell::Cell<()>>();
+   |                    ^^^^^^^^^^^^^^^^^^^ `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<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error[E0277]: `Cell<u8>` cannot be shared between threads safely
+  --> $DIR/suggest-cell.rs:17:20
+   |
+LL |     require_sync::<std::cell::Cell<u8>>();
+   |                    ^^^^^^^^^^^^^^^^^^^ `Cell<u8>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Cell<u8>`
+   = 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<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error[E0277]: `Cell<i32>` cannot be shared between threads safely
+  --> $DIR/suggest-cell.rs:22:20
+   |
+LL |     require_sync::<std::cell::Cell<i32>>();
+   |                    ^^^^^^^^^^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Cell<i32>`
+   = 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<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error[E0277]: `Cell<bool>` cannot be shared between threads safely
+  --> $DIR/suggest-cell.rs:27:20
+   |
+LL |     require_sync::<std::cell::Cell<bool>>();
+   |                    ^^^^^^^^^^^^^^^^^^^^^ `Cell<bool>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Cell<bool>`
+   = 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<T: 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 00000000000..82fca45b1a4
--- /dev/null
+++ b/tests/ui/sync/suggest-once-cell.rs
@@ -0,0 +1,12 @@
+#![feature(once_cell)]
+
+fn require_sync<T: Sync>() {}
+//~^ NOTE required by this bound in `require_sync`
+//~| NOTE required by a bound in `require_sync`
+
+fn main() {
+    require_sync::<std::cell::OnceCell<()>>();
+    //~^ 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 00000000000..fadf05374d8
--- /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::<std::cell::OnceCell<()>>();
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^ `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<T: 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 00000000000..6b972ae0962
--- /dev/null
+++ b/tests/ui/sync/suggest-ref-cell.rs
@@ -0,0 +1,12 @@
+#![feature(once_cell)]
+
+fn require_sync<T: Sync>() {}
+//~^ NOTE required by this bound in `require_sync`
+//~| NOTE required by a bound in `require_sync`
+
+fn main() {
+    require_sync::<std::cell::RefCell<()>>();
+    //~^ 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 00000000000..9e8b8fcb42e
--- /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::<std::cell::RefCell<()>>();
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ `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<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.