Skip to content

Commit 508cf6b

Browse files
committed
Move MutMutexLock into Methods lint pass
1 parent 2f0ed0a commit 508cf6b

File tree

7 files changed

+74
-75
lines changed

7 files changed

+74
-75
lines changed

clippy_lints/src/lib.register_all.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
182182
LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
183183
LintId::of(methods::MAP_FLATTEN),
184184
LintId::of(methods::MAP_IDENTITY),
185+
LintId::of(methods::MUT_MUTEX_LOCK),
185186
LintId::of(methods::NEEDLESS_OPTION_AS_DEREF),
186187
LintId::of(methods::NEEDLESS_OPTION_TAKE),
187188
LintId::of(methods::NEEDLESS_SPLITN),
@@ -226,7 +227,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
226227
LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
227228
LintId::of(mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION),
228229
LintId::of(mut_key::MUTABLE_KEY_TYPE),
229-
LintId::of(mut_mutex_lock::MUT_MUTEX_LOCK),
230230
LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
231231
LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
232232
LintId::of(needless_bool::BOOL_COMPARISON),

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ store.register_lints(&[
329329
methods::MAP_FLATTEN,
330330
methods::MAP_IDENTITY,
331331
methods::MAP_UNWRAP_OR,
332+
methods::MUT_MUTEX_LOCK,
332333
methods::NAIVE_BYTECOUNT,
333334
methods::NEEDLESS_OPTION_AS_DEREF,
334335
methods::NEEDLESS_OPTION_TAKE,
@@ -389,7 +390,6 @@ store.register_lints(&[
389390
module_style::SELF_NAMED_MODULE_FILES,
390391
mut_key::MUTABLE_KEY_TYPE,
391392
mut_mut::MUT_MUT,
392-
mut_mutex_lock::MUT_MUTEX_LOCK,
393393
mut_reference::UNNECESSARY_MUT_PASSED,
394394
mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL,
395395
mutex_atomic::MUTEX_ATOMIC,

clippy_lints/src/lib.register_style.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
7070
LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
7171
LintId::of(methods::MAP_CLONE),
7272
LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
73+
LintId::of(methods::MUT_MUTEX_LOCK),
7374
LintId::of(methods::NEW_RET_NO_SELF),
7475
LintId::of(methods::OBFUSCATED_IF_ELSE),
7576
LintId::of(methods::OK_EXPECT),
@@ -89,7 +90,6 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
8990
LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
9091
LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
9192
LintId::of(misc_early::REDUNDANT_PATTERN),
92-
LintId::of(mut_mutex_lock::MUT_MUTEX_LOCK),
9393
LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
9494
LintId::of(needless_late_init::NEEDLESS_LATE_INIT),
9595
LintId::of(needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS),

clippy_lints/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ mod mixed_read_write_in_expression;
291291
mod module_style;
292292
mod mut_key;
293293
mod mut_mut;
294-
mod mut_mutex_lock;
295294
mod mut_reference;
296295
mod mutable_debug_assertion;
297296
mod mutex_atomic;
@@ -815,7 +814,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
815814
store.register_late_pass(|| Box::new(if_let_mutex::IfLetMutex));
816815
store.register_late_pass(|| Box::new(if_not_else::IfNotElse));
817816
store.register_late_pass(|| Box::new(equatable_if_let::PatternEquality));
818-
store.register_late_pass(|| Box::new(mut_mutex_lock::MutMutexLock));
819817
store.register_late_pass(|| Box::new(manual_async_fn::ManualAsyncFn));
820818
store.register_late_pass(|| Box::new(vec_resize_to_zero::VecResizeToZero));
821819
store.register_late_pass(|| Box::new(panic_in_result_fn::PanicInResultFn));

clippy_lints/src/methods/mod.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ mod map_err_ignore;
5151
mod map_flatten;
5252
mod map_identity;
5353
mod map_unwrap_or;
54+
mod mut_mutex_lock;
5455
mod needless_option_as_deref;
5556
mod needless_option_take;
5657
mod no_effect_replace;
@@ -2642,6 +2643,42 @@ declare_clippy_lint! {
26422643
"`map_err` should not ignore the original error"
26432644
}
26442645

2646+
declare_clippy_lint! {
2647+
/// ### What it does
2648+
/// Checks for `&mut Mutex::lock` calls
2649+
///
2650+
/// ### Why is this bad?
2651+
/// `Mutex::lock` is less efficient than
2652+
/// calling `Mutex::get_mut`. In addition you also have a statically
2653+
/// guarantee that the mutex isn't locked, instead of just a runtime
2654+
/// guarantee.
2655+
///
2656+
/// ### Example
2657+
/// ```rust
2658+
/// use std::sync::{Arc, Mutex};
2659+
///
2660+
/// let mut value_rc = Arc::new(Mutex::new(42_u8));
2661+
/// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
2662+
///
2663+
/// let mut value = value_mutex.lock().unwrap();
2664+
/// *value += 1;
2665+
/// ```
2666+
/// Use instead:
2667+
/// ```rust
2668+
/// use std::sync::{Arc, Mutex};
2669+
///
2670+
/// let mut value_rc = Arc::new(Mutex::new(42_u8));
2671+
/// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
2672+
///
2673+
/// let value = value_mutex.get_mut().unwrap();
2674+
/// *value += 1;
2675+
/// ```
2676+
#[clippy::version = "1.49.0"]
2677+
pub MUT_MUTEX_LOCK,
2678+
style,
2679+
"`&mut Mutex::lock` does unnecessary locking"
2680+
}
2681+
26452682
pub struct Methods {
26462683
avoid_breaking_exported_api: bool,
26472684
msrv: Option<RustcVersion>,
@@ -2753,6 +2790,7 @@ impl_lint_pass!(Methods => [
27532790
MANUAL_OK_OR,
27542791
MAP_CLONE,
27552792
MAP_ERR_IGNORE,
2793+
MUT_MUTEX_LOCK,
27562794
]);
27572795

27582796
/// Extracts a method call name, args, and `Span` of the method name.
@@ -3081,6 +3119,9 @@ impl Methods {
30813119
}
30823120
}
30833121
},
3122+
("lock", []) => {
3123+
mut_mutex_lock::check(cx, expr, recv, span);
3124+
},
30843125
(name @ ("map" | "map_err"), [m_arg]) => {
30853126
if name == "map" {
30863127
map_clone::check(cx, expr, recv, m_arg, self.msrv);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::ty::is_type_diagnostic_item;
3+
use if_chain::if_chain;
4+
use rustc_errors::Applicability;
5+
use rustc_hir::{Expr, Mutability};
6+
use rustc_lint::LateContext;
7+
use rustc_middle::ty;
8+
use rustc_span::{sym, Span};
9+
10+
use super::MUT_MUTEX_LOCK;
11+
12+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>, recv: &'tcx Expr<'tcx>, name_span: Span) {
13+
if_chain! {
14+
if let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind();
15+
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(ex.hir_id);
16+
if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
17+
if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Mutex);
18+
then {
19+
span_lint_and_sugg(
20+
cx,
21+
MUT_MUTEX_LOCK,
22+
name_span,
23+
"calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference",
24+
"change this to",
25+
"get_mut".to_owned(),
26+
Applicability::MaybeIncorrect,
27+
);
28+
}
29+
}
30+
}

clippy_lints/src/mut_mutex_lock.rs

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)