Skip to content

Commit 37d75da

Browse files
committed
make match_like_matches_macro only apply to matches with a wildcard
1 parent 1740dda commit 37d75da

8 files changed

+77
-54
lines changed

clippy_lints/src/assign_ops.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ fn is_commutative(op: hir::BinOpKind) -> bool {
237237
use rustc_hir::BinOpKind::{
238238
Add, And, BitAnd, BitOr, BitXor, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Rem, Shl, Shr, Sub,
239239
};
240-
#[allow(clippy::match_like_matches_macro)]
241240
match op {
242241
Add | Mul | And | Or | BitXor | BitAnd | BitOr | Eq | Ne => true,
243242
Sub | Div | Rem | Shl | Shr | Lt | Le | Ge | Gt => false,

clippy_lints/src/matches.rs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -446,11 +446,12 @@ declare_clippy_lint! {
446446
}
447447

448448
declare_clippy_lint! {
449-
/// **What it does:** Checks for `match` expressions producing a `bool` that could be written using `matches!`
449+
/// **What it does:** Checks for `match` or `if let` expressions producing a
450+
/// `bool` that could be written using `matches!`
450451
///
451452
/// **Why is this bad?** Readability and needless complexity.
452453
///
453-
/// **Known problems:** This can turn an intentionally exhaustive match into a non-exhaustive one.
454+
/// **Known problems:** None
454455
///
455456
/// **Example:**
456457
/// ```rust
@@ -462,8 +463,14 @@ declare_clippy_lint! {
462463
/// _ => false,
463464
/// };
464465
///
466+
/// let a = if let Some(0) = x {
467+
/// true
468+
/// } else {
469+
/// false
470+
/// };
471+
///
465472
/// // Good
466-
/// let a = matches!(x, Some(5));
473+
/// let a = matches!(x, Some(0));
467474
/// ```
468475
pub MATCH_LIKE_MATCHES_MACRO,
469476
style,
@@ -499,9 +506,8 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
499506
return;
500507
}
501508

502-
if !redundant_pattern_match::check(cx, expr) {
503-
check_match_like_matches(cx, expr);
504-
}
509+
redundant_pattern_match::check(cx, expr);
510+
check_match_like_matches(cx, expr);
505511

506512
if let ExprKind::Match(ref ex, ref arms, MatchSource::Normal) = expr.kind {
507513
check_single_match(cx, ex, arms, expr);
@@ -1068,6 +1074,7 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr
10681074
if_chain! {
10691075
if arms.len() == 2;
10701076
if cx.tables().expr_ty(expr).is_bool();
1077+
if is_wild(&arms[1].pat);
10711078
if let Some(first) = find_bool_lit(&arms[0].body.kind, desugared);
10721079
if let Some(second) = find_bool_lit(&arms[1].body.kind, desugared);
10731080
if first != second;
@@ -1437,16 +1444,14 @@ mod redundant_pattern_match {
14371444
use rustc_mir::const_eval::is_const_fn;
14381445
use rustc_span::source_map::Symbol;
14391446

1440-
pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {
1447+
pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
14411448
if let ExprKind::Match(op, arms, ref match_source) = &expr.kind {
14421449
match match_source {
14431450
MatchSource::Normal => find_sugg_for_match(cx, expr, op, arms),
14441451
MatchSource::IfLetDesugar { .. } => find_sugg_for_if_let(cx, expr, op, arms, "if"),
14451452
MatchSource::WhileLetDesugar => find_sugg_for_if_let(cx, expr, op, arms, "while"),
1446-
_ => false,
1453+
_ => {},
14471454
}
1448-
} else {
1449-
false
14501455
}
14511456
}
14521457

@@ -1456,7 +1461,7 @@ mod redundant_pattern_match {
14561461
op: &Expr<'_>,
14571462
arms: &[Arm<'_>],
14581463
keyword: &'static str,
1459-
) -> bool {
1464+
) {
14601465
fn find_suggestion(cx: &LateContext<'_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> {
14611466
if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") {
14621467
return Some("is_ok()");
@@ -1487,7 +1492,7 @@ mod redundant_pattern_match {
14871492
};
14881493
let good_method = match good_method {
14891494
Some(method) => method,
1490-
None => return false,
1495+
None => return,
14911496
};
14921497

14931498
// check that `while_let_on_iterator` lint does not trigger
@@ -1497,7 +1502,7 @@ mod redundant_pattern_match {
14971502
if method_path.ident.name == sym!(next);
14981503
if match_trait_method(cx, op, &paths::ITERATOR);
14991504
then {
1500-
return false;
1505+
return;
15011506
}
15021507
}
15031508

@@ -1526,15 +1531,9 @@ mod redundant_pattern_match {
15261531
);
15271532
},
15281533
);
1529-
true
15301534
}
15311535

1532-
fn find_sugg_for_match<'tcx>(
1533-
cx: &LateContext<'tcx>,
1534-
expr: &'tcx Expr<'_>,
1535-
op: &Expr<'_>,
1536-
arms: &[Arm<'_>],
1537-
) -> bool {
1536+
fn find_sugg_for_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) {
15381537
if arms.len() == 2 {
15391538
let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind);
15401539

@@ -1599,10 +1598,8 @@ mod redundant_pattern_match {
15991598
);
16001599
},
16011600
);
1602-
return true;
16031601
}
16041602
}
1605-
false
16061603
}
16071604

16081605
#[allow(clippy::too_many_arguments)]
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,36 @@
11
// run-rustfix
22

33
#![warn(clippy::match_like_matches_macro)]
4+
#![allow(unreachable_patterns)]
45

56
fn main() {
67
let x = Some(5);
78

89
// Lint
910
let _y = matches!(x, Some(0));
1011

12+
// Lint
13+
let _w = matches!(x, Some(_));
14+
1115
// Turn into is_none
1216
let _z = x.is_none();
1317

1418
// Lint
15-
let _z = !matches!(x, Some(r) if r == 0);
19+
let _zz = !matches!(x, Some(r) if r == 0);
1620

1721
// Lint
18-
let _zz = matches!(x, Some(5));
22+
let _zzz = matches!(x, Some(5));
1923

2024
// No lint
2125
let _a = match x {
2226
Some(_) => false,
23-
None => false,
27+
_ => false,
2428
};
2529

2630
// No lint
27-
let _a = match x {
31+
let _ab = match x {
2832
Some(0) => false,
29-
Some(_) => true,
33+
_ => true,
3034
None => false,
3135
};
3236
}
Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// run-rustfix
22

33
#![warn(clippy::match_like_matches_macro)]
4+
#![allow(unreachable_patterns)]
45

56
fn main() {
67
let x = Some(5);
@@ -11,31 +12,37 @@ fn main() {
1112
_ => false,
1213
};
1314

15+
// Lint
16+
let _w = match x {
17+
Some(_) => true,
18+
_ => false,
19+
};
20+
1421
// Turn into is_none
1522
let _z = match x {
1623
Some(_) => false,
1724
None => true,
1825
};
1926

2027
// Lint
21-
let _z = match x {
28+
let _zz = match x {
2229
Some(r) if r == 0 => false,
2330
_ => true,
2431
};
2532

2633
// Lint
27-
let _zz = if let Some(5) = x { true } else { false };
34+
let _zzz = if let Some(5) = x { true } else { false };
2835

2936
// No lint
3037
let _a = match x {
3138
Some(_) => false,
32-
None => false,
39+
_ => false,
3340
};
3441

3542
// No lint
36-
let _a = match x {
43+
let _ab = match x {
3744
Some(0) => false,
38-
Some(_) => true,
45+
_ => true,
3946
None => false,
4047
};
4148
}
Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: match expression looks like `matches!` macro
2-
--> $DIR/match_expr_like_matches_macro.rs:9:14
2+
--> $DIR/match_expr_like_matches_macro.rs:10:14
33
|
44
LL | let _y = match x {
55
| ______________^
@@ -10,8 +10,18 @@ LL | | };
1010
|
1111
= note: `-D clippy::match-like-matches-macro` implied by `-D warnings`
1212

13+
error: match expression looks like `matches!` macro
14+
--> $DIR/match_expr_like_matches_macro.rs:16:14
15+
|
16+
LL | let _w = match x {
17+
| ______________^
18+
LL | | Some(_) => true,
19+
LL | | _ => false,
20+
LL | | };
21+
| |_____^ help: try this: `matches!(x, Some(_))`
22+
1323
error: redundant pattern matching, consider using `is_none()`
14-
--> $DIR/match_expr_like_matches_macro.rs:15:14
24+
--> $DIR/match_expr_like_matches_macro.rs:22:14
1525
|
1626
LL | let _z = match x {
1727
| ______________^
@@ -23,20 +33,20 @@ LL | | };
2333
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
2434

2535
error: match expression looks like `matches!` macro
26-
--> $DIR/match_expr_like_matches_macro.rs:21:14
36+
--> $DIR/match_expr_like_matches_macro.rs:28:15
2737
|
28-
LL | let _z = match x {
29-
| ______________^
38+
LL | let _zz = match x {
39+
| _______________^
3040
LL | | Some(r) if r == 0 => false,
3141
LL | | _ => true,
3242
LL | | };
3343
| |_____^ help: try this: `!matches!(x, Some(r) if r == 0)`
3444

3545
error: if let .. else expression looks like `matches!` macro
36-
--> $DIR/match_expr_like_matches_macro.rs:27:15
46+
--> $DIR/match_expr_like_matches_macro.rs:34:16
3747
|
38-
LL | let _zz = if let Some(5) = x { true } else { false };
39-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))`
48+
LL | let _zzz = if let Some(5) = x { true } else { false };
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))`
4050

41-
error: aborting due to 4 previous errors
51+
error: aborting due to 5 previous errors
4252

tests/ui/question_mark.fixed

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ pub enum SeemsOption<T> {
2323

2424
impl<T> SeemsOption<T> {
2525
pub fn is_none(&self) -> bool {
26-
matches!(*self, SeemsOption::None)
26+
match *self {
27+
SeemsOption::None => true,
28+
SeemsOption::Some(_) => false,
29+
}
2730
}
2831
}
2932

tests/ui/question_mark.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ pub enum SeemsOption<T> {
2525

2626
impl<T> SeemsOption<T> {
2727
pub fn is_none(&self) -> bool {
28-
matches!(*self, SeemsOption::None)
28+
match *self {
29+
SeemsOption::None => true,
30+
SeemsOption::Some(_) => false,
31+
}
2932
}
3033
}
3134

tests/ui/question_mark.stderr

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,23 @@ LL | | }
99
= note: `-D clippy::question-mark` implied by `-D warnings`
1010

1111
error: this block may be rewritten with the `?` operator
12-
--> $DIR/question_mark.rs:47:9
12+
--> $DIR/question_mark.rs:50:9
1313
|
1414
LL | / if (self.opt).is_none() {
1515
LL | | return None;
1616
LL | | }
1717
| |_________^ help: replace it with: `(self.opt)?;`
1818

1919
error: this block may be rewritten with the `?` operator
20-
--> $DIR/question_mark.rs:51:9
20+
--> $DIR/question_mark.rs:54:9
2121
|
2222
LL | / if self.opt.is_none() {
2323
LL | | return None
2424
LL | | }
2525
| |_________^ help: replace it with: `self.opt?;`
2626

2727
error: this block may be rewritten with the `?` operator
28-
--> $DIR/question_mark.rs:55:17
28+
--> $DIR/question_mark.rs:58:17
2929
|
3030
LL | let _ = if self.opt.is_none() {
3131
| _________________^
@@ -36,7 +36,7 @@ LL | | };
3636
| |_________^ help: replace it with: `Some(self.opt?)`
3737

3838
error: this if-let-else may be rewritten with the `?` operator
39-
--> $DIR/question_mark.rs:61:17
39+
--> $DIR/question_mark.rs:64:17
4040
|
4141
LL | let _ = if let Some(x) = self.opt {
4242
| _________________^
@@ -47,31 +47,31 @@ LL | | };
4747
| |_________^ help: replace it with: `self.opt?`
4848

4949
error: this block may be rewritten with the `?` operator
50-
--> $DIR/question_mark.rs:78:9
50+
--> $DIR/question_mark.rs:81:9
5151
|
5252
LL | / if self.opt.is_none() {
5353
LL | | return None;
5454
LL | | }
5555
| |_________^ help: replace it with: `self.opt.as_ref()?;`
5656

5757
error: this block may be rewritten with the `?` operator
58-
--> $DIR/question_mark.rs:86:9
58+
--> $DIR/question_mark.rs:89:9
5959
|
6060
LL | / if self.opt.is_none() {
6161
LL | | return None;
6262
LL | | }
6363
| |_________^ help: replace it with: `self.opt.as_ref()?;`
6464

6565
error: this block may be rewritten with the `?` operator
66-
--> $DIR/question_mark.rs:94:9
66+
--> $DIR/question_mark.rs:97:9
6767
|
6868
LL | / if self.opt.is_none() {
6969
LL | | return None;
7070
LL | | }
7171
| |_________^ help: replace it with: `self.opt.as_ref()?;`
7272

7373
error: this if-let-else may be rewritten with the `?` operator
74-
--> $DIR/question_mark.rs:101:26
74+
--> $DIR/question_mark.rs:104:26
7575
|
7676
LL | let v: &Vec<_> = if let Some(ref v) = self.opt {
7777
| __________________________^
@@ -82,7 +82,7 @@ LL | | };
8282
| |_________^ help: replace it with: `self.opt.as_ref()?`
8383

8484
error: this if-let-else may be rewritten with the `?` operator
85-
--> $DIR/question_mark.rs:111:17
85+
--> $DIR/question_mark.rs:114:17
8686
|
8787
LL | let v = if let Some(v) = self.opt {
8888
| _________________^
@@ -93,7 +93,7 @@ LL | | };
9393
| |_________^ help: replace it with: `self.opt?`
9494

9595
error: this block may be rewritten with the `?` operator
96-
--> $DIR/question_mark.rs:126:5
96+
--> $DIR/question_mark.rs:129:5
9797
|
9898
LL | / if f().is_none() {
9999
LL | | return None;

0 commit comments

Comments
 (0)