mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 21:23:56 +00:00
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
This commit is contained in:
commit
e16d42f540
3 changed files with 37 additions and 23 deletions
|
@ -14,7 +14,9 @@ declare_clippy_lint! {
|
||||||
/// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`.
|
/// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`.
|
||||||
///
|
///
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
/// `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),
|
/// `Arc<T>` is an Atomic `RC<T>` and guarantees that updates to the reference counter are
|
||||||
|
/// Atomic. This is useful in multiprocessing scenarios. To send an `Arc<T>` across processes
|
||||||
|
/// 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),
|
||||||
/// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
|
/// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
|
@ -34,7 +36,7 @@ declare_clippy_lint! {
|
||||||
#[clippy::version = "1.72.0"]
|
#[clippy::version = "1.72.0"]
|
||||||
pub ARC_WITH_NON_SEND_SYNC,
|
pub ARC_WITH_NON_SEND_SYNC,
|
||||||
suspicious,
|
suspicious,
|
||||||
"using `Arc` with a type that does not implement `Send` or `Sync`"
|
"using `Arc` with a type that does not implement `Send` and `Sync`"
|
||||||
}
|
}
|
||||||
declare_lint_pass!(ArcWithNonSendSync => [ARC_WITH_NON_SEND_SYNC]);
|
declare_lint_pass!(ArcWithNonSendSync => [ARC_WITH_NON_SEND_SYNC]);
|
||||||
|
|
||||||
|
@ -61,19 +63,25 @@ impl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync {
|
||||||
cx,
|
cx,
|
||||||
ARC_WITH_NON_SEND_SYNC,
|
ARC_WITH_NON_SEND_SYNC,
|
||||||
expr.span,
|
expr.span,
|
||||||
"usage of an `Arc` that is not `Send` or `Sync`",
|
"usage of an `Arc` that is not `Send` and `Sync`",
|
||||||
|diag| {
|
|diag| {
|
||||||
with_forced_trimmed_paths!({
|
with_forced_trimmed_paths!({
|
||||||
|
diag.note(format!("`Arc<{arg_ty}>` is not `Send` and `Sync` as:"));
|
||||||
|
|
||||||
if !is_send {
|
if !is_send {
|
||||||
diag.note(format!("the trait `Send` is not implemented for `{arg_ty}`"));
|
diag.note(format!("- the trait `Send` is not implemented for `{arg_ty}`"));
|
||||||
}
|
}
|
||||||
if !is_sync {
|
if !is_sync {
|
||||||
diag.note(format!("the trait `Sync` is not implemented for `{arg_ty}`"));
|
diag.note(format!("- the trait `Sync` is not implemented for `{arg_ty}`"));
|
||||||
}
|
}
|
||||||
|
|
||||||
diag.note(format!("required for `{ty}` to implement `Send` and `Sync`"));
|
diag.help("consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types");
|
||||||
|
|
||||||
diag.help("consider using an `Rc` instead or wrapping the inner type with a `Mutex`");
|
diag.note("if you intend to use `Arc` with `Send` and `Sync` traits");
|
||||||
|
|
||||||
|
diag.note(format!(
|
||||||
|
"wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `{arg_ty}`"
|
||||||
|
));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -33,16 +33,16 @@ fn main() {
|
||||||
let _ = Arc::new(42);
|
let _ = Arc::new(42);
|
||||||
|
|
||||||
let _ = Arc::new(RefCell::new(42));
|
let _ = Arc::new(RefCell::new(42));
|
||||||
//~^ ERROR: usage of an `Arc` that is not `Send` or `Sync`
|
//~^ ERROR: usage of an `Arc` that is not `Send` and `Sync`
|
||||||
//~| NOTE: the trait `Sync` is not implemented for `RefCell<i32>`
|
//~| NOTE: the trait `Sync` is not implemented for `RefCell<i32>`
|
||||||
|
|
||||||
let mutex = Mutex::new(1);
|
let mutex = Mutex::new(1);
|
||||||
let _ = Arc::new(mutex.lock().unwrap());
|
let _ = Arc::new(mutex.lock().unwrap());
|
||||||
//~^ ERROR: usage of an `Arc` that is not `Send` or `Sync`
|
//~^ ERROR: usage of an `Arc` that is not `Send` and `Sync`
|
||||||
//~| NOTE: the trait `Send` is not implemented for `MutexGuard<'_, i32>`
|
//~| NOTE: the trait `Send` is not implemented for `MutexGuard<'_, i32>`
|
||||||
|
|
||||||
let _ = Arc::new(&42 as *const i32);
|
let _ = Arc::new(&42 as *const i32);
|
||||||
//~^ ERROR: usage of an `Arc` that is not `Send` or `Sync`
|
//~^ ERROR: usage of an `Arc` that is not `Send` and `Sync`
|
||||||
//~| NOTE: the trait `Send` is not implemented for `*const i32`
|
//~| NOTE: the trait `Send` is not implemented for `*const i32`
|
||||||
//~| NOTE: the trait `Sync` is not implemented for `*const i32`
|
//~| NOTE: the trait `Sync` is not implemented for `*const i32`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,41 @@
|
||||||
error: usage of an `Arc` that is not `Send` or `Sync`
|
error: usage of an `Arc` that is not `Send` and `Sync`
|
||||||
--> $DIR/arc_with_non_send_sync.rs:35:13
|
--> $DIR/arc_with_non_send_sync.rs:35:13
|
||||||
|
|
|
|
||||||
LL | let _ = Arc::new(RefCell::new(42));
|
LL | let _ = Arc::new(RefCell::new(42));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: the trait `Sync` is not implemented for `RefCell<i32>`
|
= note: `Arc<RefCell<i32>>` is not `Send` and `Sync` as:
|
||||||
= note: required for `Arc<RefCell<i32>>` to implement `Send` and `Sync`
|
= note: - the trait `Sync` is not implemented for `RefCell<i32>`
|
||||||
= help: consider using an `Rc` instead or wrapping the inner type with a `Mutex`
|
= help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types
|
||||||
|
= note: if you intend to use `Arc` with `Send` and `Sync` traits
|
||||||
|
= note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `RefCell<i32>`
|
||||||
= note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings`
|
= note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings`
|
||||||
= help: to override `-D warnings` add `#[allow(clippy::arc_with_non_send_sync)]`
|
= help: to override `-D warnings` add `#[allow(clippy::arc_with_non_send_sync)]`
|
||||||
|
|
||||||
error: usage of an `Arc` that is not `Send` or `Sync`
|
error: usage of an `Arc` that is not `Send` and `Sync`
|
||||||
--> $DIR/arc_with_non_send_sync.rs:40:13
|
--> $DIR/arc_with_non_send_sync.rs:40:13
|
||||||
|
|
|
|
||||||
LL | let _ = Arc::new(mutex.lock().unwrap());
|
LL | let _ = Arc::new(mutex.lock().unwrap());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: the trait `Send` is not implemented for `MutexGuard<'_, i32>`
|
= note: `Arc<MutexGuard<'_, i32>>` is not `Send` and `Sync` as:
|
||||||
= note: required for `Arc<MutexGuard<'_, i32>>` to implement `Send` and `Sync`
|
= note: - the trait `Send` is not implemented for `MutexGuard<'_, i32>`
|
||||||
= help: consider using an `Rc` instead or wrapping the inner type with a `Mutex`
|
= help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types
|
||||||
|
= note: if you intend to use `Arc` with `Send` and `Sync` traits
|
||||||
|
= note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `MutexGuard<'_, i32>`
|
||||||
|
|
||||||
error: usage of an `Arc` that is not `Send` or `Sync`
|
error: usage of an `Arc` that is not `Send` and `Sync`
|
||||||
--> $DIR/arc_with_non_send_sync.rs:44:13
|
--> $DIR/arc_with_non_send_sync.rs:44:13
|
||||||
|
|
|
|
||||||
LL | let _ = Arc::new(&42 as *const i32);
|
LL | let _ = Arc::new(&42 as *const i32);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: the trait `Send` is not implemented for `*const i32`
|
= note: `Arc<*const i32>` is not `Send` and `Sync` as:
|
||||||
= note: the trait `Sync` is not implemented for `*const i32`
|
= note: - the trait `Send` is not implemented for `*const i32`
|
||||||
= note: required for `Arc<*const i32>` to implement `Send` and `Sync`
|
= note: - the trait `Sync` is not implemented for `*const i32`
|
||||||
= help: consider using an `Rc` instead or wrapping the inner type with a `Mutex`
|
= help: consider using an `Rc` instead. `Arc` does not provide benefits for non `Send` and `Sync` types
|
||||||
|
= note: if you intend to use `Arc` with `Send` and `Sync` traits
|
||||||
|
= note: wrap the inner type with a `Mutex` or implement `Send` and `Sync` for `*const i32`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue