Skip to content

Commit

Permalink
Do not trigger if_let_mutex strating from Edition 2024
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-semenyuk committed Nov 17, 2024
1 parent b829d53 commit 0f6ad32
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 7 deletions.
11 changes: 11 additions & 0 deletions clippy_lints/src/if_let_mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ use rustc_errors::Diag;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
use rustc_span::edition::Edition::Edition2024;
use rustc_span::sym;

declare_clippy_lint! {
/// ### What it does
/// Checks for `Mutex::lock` calls in `if let` expression
/// with lock calls in any of the else blocks.
///
/// ### Disabled starting in Edition 2024
/// `Mutex::lock` is effectively disabled starting in
/// Edition 2024 as `if let ... else` scoping was reworked
/// such that this is no longer an issue. See
/// [Proposal: stabilize if_let_rescope for Edition 2024](https://github.com/rust-lang/rust/issues/131154)
///
/// ### Why is this bad?
/// The Mutex lock remains held for the whole
/// `if let ... else` block and deadlocks.
Expand Down Expand Up @@ -45,6 +52,10 @@ declare_lint_pass!(IfLetMutex => [IF_LET_MUTEX]);

impl<'tcx> LateLintPass<'tcx> for IfLetMutex {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if cx.tcx.sess.edition() >= Edition2024 {
return;
}

if let Some(higher::IfLet {
let_expr,
if_then,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
--> tests/ui/if_let_mutex.rs:11:5
--> tests/ui/if_let_mutex.rs:16:5
|
LL | if let Err(locked) = m.lock() {
| ^ - this Mutex will remain locked for the entire `if let`-block...
| _____|
| |
LL | |
LL | | // ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
LL | | do_stuff(locked);
LL | | } else {
LL | | let lock = m.lock().unwrap();
Expand All @@ -19,13 +20,14 @@ LL | | };
= help: to override `-D warnings` add `#[allow(clippy::if_let_mutex)]`

error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
--> tests/ui/if_let_mutex.rs:24:5
--> tests/ui/if_let_mutex.rs:30:5
|
LL | if let Some(locked) = m.lock().unwrap().deref() {
| ^ - this Mutex will remain locked for the entire `if let`-block...
| _____|
| |
LL | |
LL | | // ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
LL | | do_stuff(locked);
LL | | } else {
LL | | let lock = m.lock().unwrap();
Expand All @@ -37,13 +39,14 @@ LL | | };
= help: move the lock call outside of the `if let ...` expression

error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
--> tests/ui/if_let_mutex.rs:46:5
--> tests/ui/if_let_mutex.rs:53:5
|
LL | if let Ok(i) = mutex.lock() {
| ^ ----- this Mutex will remain locked for the entire `if let`-block...
| _____|
| |
LL | |
LL | | // ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
LL | | do_stuff(i);
LL | | } else {
LL | | let _x = mutex.lock();
Expand All @@ -54,7 +57,7 @@ LL | | };
= help: move the lock call outside of the `if let ...` expression

error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
--> tests/ui/if_let_mutex.rs:55:5
--> tests/ui/if_let_mutex.rs:63:5
|
LL | if let Ok(_) = m1.lock() {
| ^ -- this Mutex will remain locked for the entire `if let`-block...
Expand Down
14 changes: 11 additions & 3 deletions tests/ui/if_let_mutex.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//@ compile-flags: -Zunstable-options

//@revisions: edition2021 edition2024
//@[edition2021] edition:2021
//@[edition2024] edition:2024
#![warn(clippy::if_let_mutex)]
#![allow(clippy::redundant_pattern_matching)]

Expand All @@ -9,7 +14,8 @@ fn do_stuff<T>(_: T) {}
fn if_let() {
let m = Mutex::new(1_u8);
if let Err(locked) = m.lock() {
//~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
//~[edition2021]^ if_let_mutex
// ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
do_stuff(locked);
} else {
let lock = m.lock().unwrap();
Expand All @@ -22,7 +28,8 @@ fn if_let() {
fn if_let_option() {
let m = Mutex::new(Some(0_u8));
if let Some(locked) = m.lock().unwrap().deref() {
//~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
//~[edition2021]^ if_let_mutex
// ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
do_stuff(locked);
} else {
let lock = m.lock().unwrap();
Expand All @@ -44,7 +51,8 @@ fn if_let_different_mutex() {

fn mutex_ref(mutex: &Mutex<i32>) {
if let Ok(i) = mutex.lock() {
//~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
//~[edition2021]^ if_let_mutex
// ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
do_stuff(i);
} else {
let _x = mutex.lock();
Expand Down

0 comments on commit 0f6ad32

Please sign in to comment.