Skip to content

Commit 6d0c91f

Browse files
committed
Add rustc_on_unimplemented on Sync for cell types
Suggest using a lock instead.
1 parent e1f630f commit 6d0c91f

18 files changed

+229
-5
lines changed

library/core/src/marker.rs

+56
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,62 @@ pub macro Copy($item:item) {
469469
#[cfg_attr(not(test), rustc_diagnostic_item = "Sync")]
470470
#[lang = "sync"]
471471
#[rustc_on_unimplemented(
472+
on(
473+
_Self = "std::cell::OnceCell<T>",
474+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead"
475+
),
476+
on(
477+
_Self = "std::cell::Cell<u8>",
478+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead",
479+
),
480+
on(
481+
_Self = "std::cell::Cell<u16>",
482+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU16` instead",
483+
),
484+
on(
485+
_Self = "std::cell::Cell<u32>",
486+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU32` instead",
487+
),
488+
on(
489+
_Self = "std::cell::Cell<u64>",
490+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU64` instead",
491+
),
492+
on(
493+
_Self = "std::cell::Cell<usize>",
494+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicUsize` instead",
495+
),
496+
on(
497+
_Self = "std::cell::Cell<i8>",
498+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI8` instead",
499+
),
500+
on(
501+
_Self = "std::cell::Cell<i16>",
502+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI16` instead",
503+
),
504+
on(
505+
_Self = "std::cell::Cell<i32>",
506+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead",
507+
),
508+
on(
509+
_Self = "std::cell::Cell<i64>",
510+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI64` instead",
511+
),
512+
on(
513+
_Self = "std::cell::Cell<isize>",
514+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicIsize` instead",
515+
),
516+
on(
517+
_Self = "std::cell::Cell<bool>",
518+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead",
519+
),
520+
on(
521+
_Self = "std::cell::Cell<T>",
522+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`",
523+
),
524+
on(
525+
_Self = "std::cell::RefCell<T>",
526+
note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead",
527+
),
472528
message = "`{Self}` cannot be shared between threads safely",
473529
label = "`{Self}` cannot be shared between threads safely"
474530
)]

tests/ui/async-await/issue-68112.drop_tracking.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | require_send(send_fut);
55
| ^^^^^^^^ future created by async block is not `Send`
66
|
77
= help: the trait `Sync` is not implemented for `RefCell<i32>`
8+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
89
note: future is not `Send` as it awaits another future which is not `Send`
910
--> $DIR/issue-68112.rs:34:17
1011
|
@@ -23,6 +24,7 @@ LL | require_send(send_fut);
2324
| ^^^^^^^^ future created by async block is not `Send`
2425
|
2526
= help: the trait `Sync` is not implemented for `RefCell<i32>`
27+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
2628
note: future is not `Send` as it awaits another future which is not `Send`
2729
--> $DIR/issue-68112.rs:43:17
2830
|
@@ -43,6 +45,7 @@ LL | require_send(send_fut);
4345
| required by a bound introduced by this call
4446
|
4547
= help: the trait `Sync` is not implemented for `RefCell<i32>`
48+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
4649
= note: required for `Arc<RefCell<i32>>` to implement `Send`
4750
note: required because it's used within this `async fn` body
4851
--> $DIR/issue-68112.rs:50:31

tests/ui/async-await/issue-68112.no_drop_tracking.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | require_send(send_fut);
55
| ^^^^^^^^ future created by async block is not `Send`
66
|
77
= help: the trait `Sync` is not implemented for `RefCell<i32>`
8+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
89
note: future is not `Send` as it awaits another future which is not `Send`
910
--> $DIR/issue-68112.rs:34:17
1011
|
@@ -23,6 +24,7 @@ LL | require_send(send_fut);
2324
| ^^^^^^^^ future created by async block is not `Send`
2425
|
2526
= help: the trait `Sync` is not implemented for `RefCell<i32>`
27+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
2628
note: future is not `Send` as it awaits another future which is not `Send`
2729
--> $DIR/issue-68112.rs:43:17
2830
|
@@ -43,6 +45,7 @@ LL | require_send(send_fut);
4345
| required by a bound introduced by this call
4446
|
4547
= help: the trait `Sync` is not implemented for `RefCell<i32>`
48+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
4649
= note: required for `Arc<RefCell<i32>>` to implement `Send`
4750
note: required because it's used within this `async fn` body
4851
--> $DIR/issue-68112.rs:50:31

tests/ui/generator/issue-68112.rs

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ fn test1() {
4040
require_send(send_gen);
4141
//~^ ERROR generator cannot be sent between threads
4242
//~| NOTE not `Send`
43+
//~| NOTE use `std::sync::RwLock` instead
4344
}
4445

4546
pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
@@ -66,6 +67,7 @@ fn test2() {
6667
//~| NOTE required for
6768
//~| NOTE required by a bound introduced by this call
6869
//~| NOTE captures the following types
70+
//~| NOTE use `std::sync::RwLock` instead
6971
}
7072

7173
fn main() {}

tests/ui/generator/issue-68112.stderr

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | require_send(send_gen);
55
| ^^^^^^^^ generator is not `Send`
66
|
77
= help: the trait `Sync` is not implemented for `RefCell<i32>`
8+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
89
note: generator is not `Send` as this value is used across a yield
910
--> $DIR/issue-68112.rs:36:9
1011
|
@@ -23,33 +24,34 @@ LL | fn require_send(_: impl Send) {}
2324
| ^^^^ required by this bound in `require_send`
2425

2526
error[E0277]: `RefCell<i32>` cannot be shared between threads safely
26-
--> $DIR/issue-68112.rs:63:18
27+
--> $DIR/issue-68112.rs:64:18
2728
|
2829
LL | require_send(send_gen);
2930
| ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
3031
| |
3132
| required by a bound introduced by this call
3233
|
3334
= help: the trait `Sync` is not implemented for `RefCell<i32>`
35+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
3436
= note: required for `Arc<RefCell<i32>>` to implement `Send`
3537
note: required because it's used within this generator
36-
--> $DIR/issue-68112.rs:48:5
38+
--> $DIR/issue-68112.rs:49:5
3739
|
3840
LL | || {
3941
| ^^
4042
note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
41-
--> $DIR/issue-68112.rs:45:30
43+
--> $DIR/issue-68112.rs:46:30
4244
|
4345
LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
4446
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
4547
note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
46-
--> $DIR/issue-68112.rs:53:34
48+
--> $DIR/issue-68112.rs:54:34
4749
|
4850
LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
4951
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5052
= note: required because it captures the following types: `impl Generator<Return = Arc<RefCell<i32>>>`, `()`
5153
note: required because it's used within this generator
52-
--> $DIR/issue-68112.rs:59:20
54+
--> $DIR/issue-68112.rs:60:20
5355
|
5456
LL | let send_gen = || {
5557
| ^^

tests/ui/generator/not-send-sync.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ LL | | });
1212
| |_____^ `Cell<i32>` cannot be shared between threads safely
1313
|
1414
= help: the trait `Sync` is not implemented for `Cell<i32>`
15+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
1516
= note: required for `&Cell<i32>` to implement `Send`
1617
note: required because it's used within this generator
1718
--> $DIR/not-send-sync.rs:16:17
@@ -36,6 +37,7 @@ LL | | });
3637
| |_____^ generator is not `Sync`
3738
|
3839
= help: within `[generator@$DIR/not-send-sync.rs:9:17: 9:19]`, the trait `Sync` is not implemented for `Cell<i32>`
40+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
3941
note: generator is not `Sync` as this value is used across a yield
4042
--> $DIR/not-send-sync.rs:12:9
4143
|

tests/ui/generator/print/generator-print-verbose-1.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | require_send(send_gen);
55
| ^^^^^^^^ generator is not `Send`
66
|
77
= help: the trait `Sync` is not implemented for `RefCell<i32>`
8+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
89
note: generator is not `Send` as this value is used across a yield
910
--> $DIR/generator-print-verbose-1.rs:35:9
1011
|
@@ -29,6 +30,7 @@ LL | require_send(send_gen);
2930
| required by a bound introduced by this call
3031
|
3132
= help: the trait `Sync` is not implemented for `RefCell<i32>`
33+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
3234
= note: required for `Arc<RefCell<i32>>` to implement `Send`
3335
note: required because it's used within this generator
3436
--> $DIR/generator-print-verbose-1.rs:42:5

tests/ui/generator/print/generator-print-verbose-2.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ LL | | });
1212
| |_____^ `Cell<i32>` cannot be shared between threads safely
1313
|
1414
= help: the trait `Sync` is not implemented for `Cell<i32>`
15+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
1516
= note: required for `&'_#4r Cell<i32>` to implement `Send`
1617
note: required because it's used within this generator
1718
--> $DIR/generator-print-verbose-2.rs:19:17
@@ -36,6 +37,7 @@ LL | | });
3637
| |_____^ generator is not `Sync`
3738
|
3839
= help: within `[main::{closure#0} upvar_tys=() {Cell<i32>, ()}]`, the trait `Sync` is not implemented for `Cell<i32>`
40+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
3941
note: generator is not `Sync` as this value is used across a yield
4042
--> $DIR/generator-print-verbose-2.rs:15:9
4143
|

tests/ui/issues/issue-7364.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
55
| ^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
66
|
77
= help: the trait `Sync` is not implemented for `RefCell<isize>`
8+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
89
= note: required for `Unique<RefCell<isize>>` to implement `Sync`
910
= note: required because it appears within the type `Box<RefCell<isize>>`
1011
= note: shared static variables must have a type that implements `Sync`

tests/ui/stdlib-unit-tests/not-sync.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | test::<Cell<i32>>();
55
| ^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
66
|
77
= help: the trait `Sync` is not implemented for `Cell<i32>`
8+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
89
note: required by a bound in `test`
910
--> $DIR/not-sync.rs:5:12
1011
|
@@ -18,6 +19,7 @@ LL | test::<RefCell<i32>>();
1819
| ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
1920
|
2021
= help: the trait `Sync` is not implemented for `RefCell<i32>`
22+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
2123
note: required by a bound in `test`
2224
--> $DIR/not-sync.rs:5:12
2325
|
File renamed without changes.

tests/ui/mutexguard-sync.stderr renamed to tests/ui/sync/mutexguard-sync.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL | test_sync(guard);
77
| required by a bound introduced by this call
88
|
99
= help: the trait `Sync` is not implemented for `Cell<i32>`
10+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
1011
= note: required for `MutexGuard<'_, Cell<i32>>` to implement `Sync`
1112
note: required by a bound in `test_sync`
1213
--> $DIR/mutexguard-sync.rs:5:17

tests/ui/sync/suggest-cell.rs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
fn require_sync<T: Sync>() {}
2+
//~^ NOTE required by this bound in `require_sync`
3+
//~| NOTE required by this bound in `require_sync`
4+
//~| NOTE required by this bound in `require_sync`
5+
//~| NOTE required by this bound in `require_sync`
6+
//~| NOTE required by a bound in `require_sync`
7+
//~| NOTE required by a bound in `require_sync`
8+
//~| NOTE required by a bound in `require_sync`
9+
//~| NOTE required by a bound in `require_sync`
10+
11+
fn main() {
12+
require_sync::<std::cell::Cell<()>>();
13+
//~^ ERROR `Cell<()>` cannot be shared between threads safely
14+
//~| NOTE `Cell<()>` cannot be shared between threads safely
15+
//~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`
16+
17+
require_sync::<std::cell::Cell<u8>>();
18+
//~^ ERROR `Cell<u8>` cannot be shared between threads safely
19+
//~| NOTE `Cell<u8>` cannot be shared between threads safely
20+
//~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead
21+
22+
require_sync::<std::cell::Cell<i32>>();
23+
//~^ ERROR `Cell<i32>` cannot be shared between threads safely
24+
//~| NOTE `Cell<i32>` cannot be shared between threads safely
25+
//~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
26+
27+
require_sync::<std::cell::Cell<bool>>();
28+
//~^ ERROR `Cell<bool>` cannot be shared between threads safely
29+
//~| NOTE `Cell<bool>` cannot be shared between threads safely
30+
//~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead
31+
}

tests/ui/sync/suggest-cell.stderr

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
error[E0277]: `Cell<()>` cannot be shared between threads safely
2+
--> $DIR/suggest-cell.rs:12:20
3+
|
4+
LL | require_sync::<std::cell::Cell<()>>();
5+
| ^^^^^^^^^^^^^^^^^^^ `Cell<()>` cannot be shared between threads safely
6+
|
7+
= help: the trait `Sync` is not implemented for `Cell<()>`
8+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`
9+
note: required by a bound in `require_sync`
10+
--> $DIR/suggest-cell.rs:1:20
11+
|
12+
LL | fn require_sync<T: Sync>() {}
13+
| ^^^^ required by this bound in `require_sync`
14+
15+
error[E0277]: `Cell<u8>` cannot be shared between threads safely
16+
--> $DIR/suggest-cell.rs:17:20
17+
|
18+
LL | require_sync::<std::cell::Cell<u8>>();
19+
| ^^^^^^^^^^^^^^^^^^^ `Cell<u8>` cannot be shared between threads safely
20+
|
21+
= help: the trait `Sync` is not implemented for `Cell<u8>`
22+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead
23+
note: required by a bound in `require_sync`
24+
--> $DIR/suggest-cell.rs:1:20
25+
|
26+
LL | fn require_sync<T: Sync>() {}
27+
| ^^^^ required by this bound in `require_sync`
28+
29+
error[E0277]: `Cell<i32>` cannot be shared between threads safely
30+
--> $DIR/suggest-cell.rs:22:20
31+
|
32+
LL | require_sync::<std::cell::Cell<i32>>();
33+
| ^^^^^^^^^^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
34+
|
35+
= help: the trait `Sync` is not implemented for `Cell<i32>`
36+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
37+
note: required by a bound in `require_sync`
38+
--> $DIR/suggest-cell.rs:1:20
39+
|
40+
LL | fn require_sync<T: Sync>() {}
41+
| ^^^^ required by this bound in `require_sync`
42+
43+
error[E0277]: `Cell<bool>` cannot be shared between threads safely
44+
--> $DIR/suggest-cell.rs:27:20
45+
|
46+
LL | require_sync::<std::cell::Cell<bool>>();
47+
| ^^^^^^^^^^^^^^^^^^^^^ `Cell<bool>` cannot be shared between threads safely
48+
|
49+
= help: the trait `Sync` is not implemented for `Cell<bool>`
50+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead
51+
note: required by a bound in `require_sync`
52+
--> $DIR/suggest-cell.rs:1:20
53+
|
54+
LL | fn require_sync<T: Sync>() {}
55+
| ^^^^ required by this bound in `require_sync`
56+
57+
error: aborting due to 4 previous errors
58+
59+
For more information about this error, try `rustc --explain E0277`.

tests/ui/sync/suggest-once-cell.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(once_cell)]
2+
3+
fn require_sync<T: Sync>() {}
4+
//~^ NOTE required by this bound in `require_sync`
5+
//~| NOTE required by a bound in `require_sync`
6+
7+
fn main() {
8+
require_sync::<std::cell::OnceCell<()>>();
9+
//~^ ERROR `OnceCell<()>` cannot be shared between threads safely
10+
//~| NOTE `OnceCell<()>` cannot be shared between threads safely
11+
//~| NOTE use `std::sync::OnceLock` instead
12+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0277]: `OnceCell<()>` cannot be shared between threads safely
2+
--> $DIR/suggest-once-cell.rs:8:20
3+
|
4+
LL | require_sync::<std::cell::OnceCell<()>>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ `OnceCell<()>` cannot be shared between threads safely
6+
|
7+
= help: the trait `Sync` is not implemented for `OnceCell<()>`
8+
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead
9+
note: required by a bound in `require_sync`
10+
--> $DIR/suggest-once-cell.rs:3:20
11+
|
12+
LL | fn require_sync<T: Sync>() {}
13+
| ^^^^ required by this bound in `require_sync`
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0277`.

tests/ui/sync/suggest-ref-cell.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(once_cell)]
2+
3+
fn require_sync<T: Sync>() {}
4+
//~^ NOTE required by this bound in `require_sync`
5+
//~| NOTE required by a bound in `require_sync`
6+
7+
fn main() {
8+
require_sync::<std::cell::RefCell<()>>();
9+
//~^ ERROR `RefCell<()>` cannot be shared between threads safely
10+
//~| NOTE `RefCell<()>` cannot be shared between threads safely
11+
//~| NOTE use `std::sync::RwLock` instead
12+
}

0 commit comments

Comments
 (0)