Skip to content

Commit cf16044

Browse files
committed
Do not trigger strating from Edition 2024
1 parent b829d53 commit cf16044

File tree

4 files changed

+81
-7
lines changed

4 files changed

+81
-7
lines changed

clippy_lints/src/if_let_mutex.rs

+11
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,20 @@ use rustc_errors::Diag;
77
use rustc_hir::{Expr, ExprKind};
88
use rustc_lint::{LateContext, LateLintPass};
99
use rustc_session::declare_lint_pass;
10+
use rustc_span::edition::Edition::Edition2024;
1011
use rustc_span::sym;
1112

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

4653
impl<'tcx> LateLintPass<'tcx> for IfLetMutex {
4754
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
55+
if cx.tcx.sess.edition() >= Edition2024 {
56+
return;
57+
}
58+
4859
if let Some(higher::IfLet {
4960
let_expr,
5061
if_then,

tests/ui/if_let_mutex.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//@ compile-flags: -Zunstable-options
2+
3+
//@edition:2024
14
#![warn(clippy::if_let_mutex)]
25
#![allow(clippy::redundant_pattern_matching)]
36

@@ -9,7 +12,6 @@ fn do_stuff<T>(_: T) {}
912
fn if_let() {
1013
let m = Mutex::new(1_u8);
1114
if let Err(locked) = m.lock() {
12-
//~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
1315
do_stuff(locked);
1416
} else {
1517
let lock = m.lock().unwrap();
@@ -22,7 +24,6 @@ fn if_let() {
2224
fn if_let_option() {
2325
let m = Mutex::new(Some(0_u8));
2426
if let Some(locked) = m.lock().unwrap().deref() {
25-
//~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
2627
do_stuff(locked);
2728
} else {
2829
let lock = m.lock().unwrap();
@@ -44,7 +45,6 @@ fn if_let_different_mutex() {
4445

4546
fn mutex_ref(mutex: &Mutex<i32>) {
4647
if let Ok(i) = mutex.lock() {
47-
//~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
4848
do_stuff(i);
4949
} else {
5050
let _x = mutex.lock();

tests/ui/if_let_mutex_2021.rs

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//@edition:2021
2+
#![warn(clippy::if_let_mutex)]
3+
#![allow(clippy::redundant_pattern_matching)]
4+
5+
use std::ops::Deref;
6+
use std::sync::Mutex;
7+
8+
fn do_stuff<T>(_: T) {}
9+
10+
fn if_let() {
11+
let m = Mutex::new(1_u8);
12+
if let Err(locked) = m.lock() {
13+
//~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
14+
do_stuff(locked);
15+
} else {
16+
let lock = m.lock().unwrap();
17+
do_stuff(lock);
18+
};
19+
}
20+
21+
// This is the most common case as the above case is pretty
22+
// contrived.
23+
fn if_let_option() {
24+
let m = Mutex::new(Some(0_u8));
25+
if let Some(locked) = m.lock().unwrap().deref() {
26+
//~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
27+
do_stuff(locked);
28+
} else {
29+
let lock = m.lock().unwrap();
30+
do_stuff(lock);
31+
};
32+
}
33+
34+
// When mutexes are different don't warn
35+
fn if_let_different_mutex() {
36+
let m = Mutex::new(Some(0_u8));
37+
let other = Mutex::new(None::<u8>);
38+
if let Some(locked) = m.lock().unwrap().deref() {
39+
do_stuff(locked);
40+
} else {
41+
let lock = other.lock().unwrap();
42+
do_stuff(lock);
43+
};
44+
}
45+
46+
fn mutex_ref(mutex: &Mutex<i32>) {
47+
if let Ok(i) = mutex.lock() {
48+
//~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
49+
do_stuff(i);
50+
} else {
51+
let _x = mutex.lock();
52+
};
53+
}
54+
55+
fn multiple_mutexes(m1: &Mutex<()>, m2: &Mutex<()>) {
56+
if let Ok(_) = m1.lock() {
57+
m2.lock();
58+
} else {
59+
m1.lock();
60+
}
61+
}
62+
63+
fn main() {}

tests/ui/if_let_mutex.stderr renamed to tests/ui/if_let_mutex_2021.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
2-
--> tests/ui/if_let_mutex.rs:11:5
2+
--> tests/ui/if_let_mutex_2021.rs:12:5
33
|
44
LL | if let Err(locked) = m.lock() {
55
| ^ - this Mutex will remain locked for the entire `if let`-block...
@@ -19,7 +19,7 @@ LL | | };
1919
= help: to override `-D warnings` add `#[allow(clippy::if_let_mutex)]`
2020

2121
error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
22-
--> tests/ui/if_let_mutex.rs:24:5
22+
--> tests/ui/if_let_mutex_2021.rs:25:5
2323
|
2424
LL | if let Some(locked) = m.lock().unwrap().deref() {
2525
| ^ - this Mutex will remain locked for the entire `if let`-block...
@@ -37,7 +37,7 @@ LL | | };
3737
= help: move the lock call outside of the `if let ...` expression
3838

3939
error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
40-
--> tests/ui/if_let_mutex.rs:46:5
40+
--> tests/ui/if_let_mutex_2021.rs:47:5
4141
|
4242
LL | if let Ok(i) = mutex.lock() {
4343
| ^ ----- this Mutex will remain locked for the entire `if let`-block...
@@ -54,7 +54,7 @@ LL | | };
5454
= help: move the lock call outside of the `if let ...` expression
5555

5656
error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
57-
--> tests/ui/if_let_mutex.rs:55:5
57+
--> tests/ui/if_let_mutex_2021.rs:56:5
5858
|
5959
LL | if let Ok(_) = m1.lock() {
6060
| ^ -- this Mutex will remain locked for the entire `if let`-block...

0 commit comments

Comments
 (0)