Skip to content

Do not trigger if_let_mutex starting from Edition 2024 #13695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
/// This lint 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,5 +1,5 @@
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...
Expand All @@ -19,7 +19,7 @@ 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:29:5
|
LL | if let Some(locked) = m.lock().unwrap().deref() {
| ^ - this Mutex will remain locked for the entire `if let`-block...
Expand All @@ -37,7 +37,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:46:5
--> tests/ui/if_let_mutex.rs:51:5
|
LL | if let Ok(i) = mutex.lock() {
| ^ ----- this Mutex will remain locked for the entire `if let`-block...
Expand All @@ -54,7 +54,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:60:5
|
LL | if let Ok(_) = m1.lock() {
| ^ -- this Mutex will remain locked for the entire `if let`-block...
Expand Down
11 changes: 8 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,7 @@ 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
do_stuff(locked);
} else {
let lock = m.lock().unwrap();
Expand All @@ -22,7 +27,7 @@ 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
do_stuff(locked);
} else {
let lock = m.lock().unwrap();
Expand All @@ -44,7 +49,7 @@ 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
do_stuff(i);
} else {
let _x = mutex.lock();
Expand Down