Skip to content

Commit e16d42f

Browse files
committed
Auto merge of #11772 - partiallytyped:11714, r=blyxyas
[arc_with_non_send_sync] Improve suggested resolution Fixes: #11714 Improved the lint message for [`arc_with_non_send_sync`] to suggest using `RC` unless user needs an Arc, then suggests wrapping in a mutex, and then suggests implementing `Sync` and `Send`. --- changelog: [`arc_with_non_send_sync`]: Suggest RC over unsafe impl of Send and Sync
2 parents ba43632 + 399fe32 commit e16d42f

File tree

3 files changed

+37
-23
lines changed

3 files changed

+37
-23
lines changed

clippy_lints/src/arc_with_non_send_sync.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ declare_clippy_lint! {
1414
/// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`.
1515
///
1616
/// ### Why is this bad?
17-
/// `Arc<T>` is only `Send`/`Sync` when `T` is [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-Send-for-Arc%3CT%3E),
17+
/// `Arc<T>` is an Atomic `RC<T>` and guarantees that updates to the reference counter are
18+
/// Atomic. This is useful in multiprocessing scenarios. To send an `Arc<T>` across processes
19+
/// and make use of the atomic ref counter, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-Send-for-Arc%3CT%3E),
1820
/// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
1921
///
2022
/// ### Example
@@ -34,7 +36,7 @@ declare_clippy_lint! {
3436
#[clippy::version = "1.72.0"]
3537
pub ARC_WITH_NON_SEND_SYNC,
3638
suspicious,
37-
"using `Arc` with a type that does not implement `Send` or `Sync`"
39+
"using `Arc` with a type that does not implement `Send` and `Sync`"
3840
}
3941
declare_lint_pass!(ArcWithNonSendSync => [ARC_WITH_NON_SEND_SYNC]);
4042

@@ -61,19 +63,25 @@ impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync {
6163
cx,
6264
ARC_WITH_NON_SEND_SYNC,
6365
expr.span,
64-
"usage of an `Arc` that is not `Send` or `Sync`",
66+
"usage of an `Arc` that is not `Send` and `Sync`",
6567
|diag| {
6668
with_forced_trimmed_paths!({
69+
diag.note(format!("`Arc<{arg_ty}>` is not `Send` and `Sync` as:"));
70+
6771
if !is_send {
68-
diag.note(format!("the trait `Send` is not implemented for `{arg_ty}`"));
72+
diag.note(format!("- the trait `Send` is not implemented for `{arg_ty}`"));
6973
}
7074
if !is_sync {
71-
diag.note(format!("the trait `Sync` is not implemented for `{arg_ty}`"));
75+
diag.note(format!("- the trait `Sync` is not implemented for `{arg_ty}`"));
7276
}
7377

74-
diag.note(format!("required for `{ty}` to implement `Send` and `Sync`"));
78+
diag.help("consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types");
79+
80+
diag.note("if you intend to use `Arc` with `Send` and `Sync` traits");
7581

76-
diag.help("consider using an `Rc` instead or wrapping the inner type with a `Mutex`");
82+
diag.note(format!(
83+
"wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `{arg_ty}`"
84+
));
7785
});
7886
},
7987
);

tests/ui/arc_with_non_send_sync.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@ fn main() {
3333
let _ = Arc::new(42);
3434

3535
let _ = Arc::new(RefCell::new(42));
36-
//~^ ERROR: usage of an `Arc` that is not `Send` or `Sync`
36+
//~^ ERROR: usage of an `Arc` that is not `Send` and `Sync`
3737
//~| NOTE: the trait `Sync` is not implemented for `RefCell<i32>`
3838

3939
let mutex = Mutex::new(1);
4040
let _ = Arc::new(mutex.lock().unwrap());
41-
//~^ ERROR: usage of an `Arc` that is not `Send` or `Sync`
41+
//~^ ERROR: usage of an `Arc` that is not `Send` and `Sync`
4242
//~| NOTE: the trait `Send` is not implemented for `MutexGuard<'_, i32>`
4343

4444
let _ = Arc::new(&42 as *const i32);
45-
//~^ ERROR: usage of an `Arc` that is not `Send` or `Sync`
45+
//~^ ERROR: usage of an `Arc` that is not `Send` and `Sync`
4646
//~| NOTE: the trait `Send` is not implemented for `*const i32`
4747
//~| NOTE: the trait `Sync` is not implemented for `*const i32`
4848
}
+19-13
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,41 @@
1-
error: usage of an `Arc` that is not `Send` or `Sync`
1+
error: usage of an `Arc` that is not `Send` and `Sync`
22
--> $DIR/arc_with_non_send_sync.rs:35:13
33
|
44
LL | let _ = Arc::new(RefCell::new(42));
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: the trait `Sync` is not implemented for `RefCell<i32>`
8-
= note: required for `Arc<RefCell<i32>>` to implement `Send` and `Sync`
9-
= help: consider using an `Rc` instead or wrapping the inner type with a `Mutex`
7+
= note: `Arc<RefCell<i32>>` is not `Send` and `Sync` as:
8+
= note: - the trait `Sync` is not implemented for `RefCell<i32>`
9+
= help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types
10+
= note: if you intend to use `Arc` with `Send` and `Sync` traits
11+
= note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `RefCell<i32>`
1012
= note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings`
1113
= help: to override `-D warnings` add `#[allow(clippy::arc_with_non_send_sync)]`
1214

13-
error: usage of an `Arc` that is not `Send` or `Sync`
15+
error: usage of an `Arc` that is not `Send` and `Sync`
1416
--> $DIR/arc_with_non_send_sync.rs:40:13
1517
|
1618
LL | let _ = Arc::new(mutex.lock().unwrap());
1719
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1820
|
19-
= note: the trait `Send` is not implemented for `MutexGuard<'_, i32>`
20-
= note: required for `Arc<MutexGuard<'_, i32>>` to implement `Send` and `Sync`
21-
= help: consider using an `Rc` instead or wrapping the inner type with a `Mutex`
21+
= note: `Arc<MutexGuard<'_, i32>>` is not `Send` and `Sync` as:
22+
= note: - the trait `Send` is not implemented for `MutexGuard<'_, i32>`
23+
= help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types
24+
= note: if you intend to use `Arc` with `Send` and `Sync` traits
25+
= note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `MutexGuard<'_, i32>`
2226

23-
error: usage of an `Arc` that is not `Send` or `Sync`
27+
error: usage of an `Arc` that is not `Send` and `Sync`
2428
--> $DIR/arc_with_non_send_sync.rs:44:13
2529
|
2630
LL | let _ = Arc::new(&42 as *const i32);
2731
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
2832
|
29-
= note: the trait `Send` is not implemented for `*const i32`
30-
= note: the trait `Sync` is not implemented for `*const i32`
31-
= note: required for `Arc<*const i32>` to implement `Send` and `Sync`
32-
= help: consider using an `Rc` instead or wrapping the inner type with a `Mutex`
33+
= note: `Arc<*const i32>` is not `Send` and `Sync` as:
34+
= note: - the trait `Send` is not implemented for `*const i32`
35+
= note: - the trait `Sync` is not implemented for `*const i32`
36+
= help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types
37+
= note: if you intend to use `Arc` with `Send` and `Sync` traits
38+
= note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `*const i32`
3339

3440
error: aborting due to 3 previous errors
3541

0 commit comments

Comments
 (0)