Skip to content

single_match: fix checking of explicitly matched enums #11441

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 2 commits into from
Aug 8, 2024
Merged
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
5 changes: 2 additions & 3 deletions clippy_lints/src/matches/match_wild_enum.rs
Original file line number Diff line number Diff line change
@@ -180,9 +180,8 @@ enum CommonPrefixSearcher<'a> {
}
impl<'a> CommonPrefixSearcher<'a> {
fn with_path(&mut self, path: &'a [PathSegment<'a>]) {
match path {
[path @ .., _] => self.with_prefix(path),
[] => (),
if let [path @ .., _] = path {
self.with_prefix(path);
}
}

22 changes: 10 additions & 12 deletions clippy_lints/src/matches/overlapping_arms.rs
Original file line number Diff line number Diff line change
@@ -33,19 +33,17 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
.filter_map(|arm| {
if let Arm { pat, guard: None, .. } = *arm {
if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind {
let lhs_const = match lhs {
Some(lhs) => constant(cx, cx.typeck_results(), lhs)?,
None => {
let min_val_const = ty.numeric_min_val(cx.tcx)?;
mir_to_const(cx, mir::Const::from_ty_const(min_val_const, ty, cx.tcx))?
},
let lhs_const = if let Some(lhs) = lhs {
constant(cx, cx.typeck_results(), lhs)?
} else {
let min_val_const = ty.numeric_min_val(cx.tcx)?;
mir_to_const(cx, mir::Const::from_ty_const(min_val_const, ty, cx.tcx))?
};
let rhs_const = match rhs {
Some(rhs) => constant(cx, cx.typeck_results(), rhs)?,
None => {
let max_val_const = ty.numeric_max_val(cx.tcx)?;
mir_to_const(cx, mir::Const::from_ty_const(max_val_const, ty, cx.tcx))?
},
let rhs_const = if let Some(rhs) = rhs {
constant(cx, cx.typeck_results(), rhs)?
} else {
let max_val_const = ty.numeric_max_val(cx.tcx)?;
mir_to_const(cx, mir::Const::from_ty_const(max_val_const, ty, cx.tcx))?
};
let lhs_val = lhs_const.int_value(cx, ty)?;
let rhs_val = rhs_const.int_value(cx, ty)?;
390 changes: 260 additions & 130 deletions clippy_lints/src/matches/single_match.rs

Large diffs are not rendered by default.

20 changes: 12 additions & 8 deletions tests/ui-toml/excessive_nesting/excessive_nesting.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
//@aux-build:../../ui/auxiliary/proc_macros.rs
#![rustfmt::skip]
#![feature(custom_inner_attributes)]
#![allow(unused)]
#![allow(clippy::let_and_return)]
#![allow(clippy::redundant_closure_call)]
#![allow(clippy::no_effect)]
#![allow(clippy::unnecessary_operation)]
#![allow(clippy::never_loop)]
#![allow(clippy::needless_if)]
#![warn(clippy::excessive_nesting)]
#![allow(clippy::collapsible_if, clippy::blocks_in_conditions)]
#![allow(
unused,
clippy::let_and_return,
clippy::redundant_closure_call,
clippy::no_effect,
clippy::unnecessary_operation,
clippy::never_loop,
clippy::needless_if,
clippy::collapsible_if,
clippy::blocks_in_conditions,
clippy::single_match,
)]

#[macro_use]
extern crate proc_macros;
74 changes: 37 additions & 37 deletions tests/ui-toml/excessive_nesting/excessive_nesting.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:21:25
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:25:25
|
LL | let w = { 3 };
| ^^^^^
@@ -9,7 +9,7 @@ LL | let w = { 3 };
= help: to override `-D warnings` add `#[allow(clippy::excessive_nesting)]`

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:67:17
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:71:17
|
LL | / impl C {
LL | | pub fn c() {}
@@ -19,15 +19,15 @@ LL | | }
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:81:25
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:85:25
|
LL | let x = { 1 }; // not a warning, but cc is
| ^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:98:17
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:102:17
|
LL | / pub mod e {
LL | | pub mod f {}
@@ -37,31 +37,31 @@ LL | | } // not here
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:111:18
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:115:18
|
LL | a_but_not({{{{{{{{0}}}}}}}});
| ^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:112:12
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:116:12
|
LL | a.a({{{{{{{{{0}}}}}}}}});
| ^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:113:12
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:117:12
|
LL | (0, {{{{{{{1}}}}}}});
| ^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:118:25
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:122:25
|
LL | if true {
| _________________________^
@@ -74,7 +74,7 @@ LL | | }
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:130:29
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:134:29
|
LL | let z = (|| {
| _____________________________^
@@ -86,207 +86,207 @@ LL | | })();
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:149:13
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:153:13
|
LL | y += {{{{{5}}}}};
| ^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:150:20
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:154:20
|
LL | let z = y + {{{{{{{{{5}}}}}}}}};
| ^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:151:12
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:155:12
|
LL | [0, {{{{{{{{{{0}}}}}}}}}}];
| ^^^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:152:25
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:156:25
|
LL | let mut xx = [0; {{{{{{{{100}}}}}}}}];
| ^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:153:11
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:157:11
|
LL | xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:154:13
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:158:13
|
LL | &mut {{{{{{{{{{y}}}}}}}}}};
| ^^^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:156:17
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:160:17
|
LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}}
| ^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:156:28
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:160:28
|
LL | for i in {{{{xx}}}} {{{{{{{{}}}}}}}}
| ^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:158:28
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:162:28
|
LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}}
| ^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:158:48
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:162:48
|
LL | while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}}
| ^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:160:14
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:14
|
LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}}
| ^^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:160:35
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:35
|
LL | while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}}
| ^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:162:23
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:166:23
|
LL | let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:8
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:168:8
|
LL | {{{{1;}}}}..{{{{{{3}}}}}};
| ^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:20
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:168:20
|
LL | {{{{1;}}}}..{{{{{{3}}}}}};
| ^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:165:8
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:169:8
|
LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}};
| ^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:165:21
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:169:21
|
LL | {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:166:10
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:170:10
|
LL | ..{{{{{{{5}}}}}}};
| ^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:167:11
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:171:11
|
LL | ..={{{{{3}}}}};
| ^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:168:8
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:172:8
|
LL | {{{{{1;}}}}}..;
| ^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:170:20
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:174:20
|
LL | loop { break {{{{1}}}} };
| ^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:171:13
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:175:13
|
LL | loop {{{{{{}}}}}}
| ^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:173:14
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:177:14
|
LL | match {{{{{{true}}}}}} {
| ^^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:174:20
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:178:20
|
LL | true => {{{{}}}},
| ^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:175:21
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:179:21
|
LL | false => {{{{}}}},
| ^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:181:17
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:185:17
|
LL | / {
LL | | println!("warning! :)");
@@ -296,15 +296,15 @@ LL | | }
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:190:28
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:194:28
|
LL | async fn c() -> u32 {{{{{{{0}}}}}}}
| ^^^^^^^^^
|
= help: try refactoring your code to minimize nesting

error: this block is too nested
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:196:8
--> tests/ui-toml/excessive_nesting/excessive_nesting.rs:200:8
|
LL | {{{{b().await}}}};
| ^^^^^^^^^^^
3 changes: 2 additions & 1 deletion tests/ui/crashes/ice-6254.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,8 @@
// panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())',
// compiler/rustc_mir_build/src/thir/pattern/_match.rs:2030:5

#[allow(clippy::derive_partial_eq_without_eq)]
#![allow(clippy::derive_partial_eq_without_eq, clippy::single_match)]

#[derive(PartialEq)]
struct Foo(i32);
const FOO_REF_REF: &&Foo = &&Foo(42);
2 changes: 1 addition & 1 deletion tests/ui/patterns.fixed
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@aux-build:proc_macros.rs
#![warn(clippy::all)]
#![allow(unused)]
#![allow(clippy::uninlined_format_args)]
#![allow(clippy::uninlined_format_args, clippy::single_match)]

#[macro_use]
extern crate proc_macros;
2 changes: 1 addition & 1 deletion tests/ui/patterns.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@aux-build:proc_macros.rs
#![warn(clippy::all)]
#![allow(unused)]
#![allow(clippy::uninlined_format_args)]
#![allow(clippy::uninlined_format_args, clippy::single_match)]

#[macro_use]
extern crate proc_macros;
43 changes: 43 additions & 0 deletions tests/ui/single_match.fixed
Original file line number Diff line number Diff line change
@@ -253,3 +253,46 @@ mod issue8634 {
}
}
}

fn issue11365() {
enum Foo {
A,
B,
C,
}
use Foo::{A, B, C};

match Some(A) {
Some(A | B | C) => println!(),
None => {},
}

match Some(A) {
Some(A | B) => println!(),
Some { 0: C } | None => {},
}

match [A, A] {
[A, _] => println!(),
[_, A | B | C] => {},
}

match Ok::<_, u32>(Some(A)) {
Ok(Some(A)) => println!(),
Err(_) | Ok(None | Some(B | C)) => {},
}

if let Ok(Some(A)) = Ok::<_, u32>(Some(A)) { println!() }

match &Some(A) {
Some(A | B | C) => println!(),
None => {},
}

match &Some(A) {
&Some(A | B | C) => println!(),
None => {},
}

if let Some(A | B) = &Some(A) { println!() }
}
49 changes: 49 additions & 0 deletions tests/ui/single_match.rs
Original file line number Diff line number Diff line change
@@ -311,3 +311,52 @@ mod issue8634 {
}
}
}

fn issue11365() {
enum Foo {
A,
B,
C,
}
use Foo::{A, B, C};

match Some(A) {
Some(A | B | C) => println!(),
None => {},
}

match Some(A) {
Some(A | B) => println!(),
Some { 0: C } | None => {},
}

match [A, A] {
[A, _] => println!(),
[_, A | B | C] => {},
}

match Ok::<_, u32>(Some(A)) {
Ok(Some(A)) => println!(),
Err(_) | Ok(None | Some(B | C)) => {},
}

match Ok::<_, u32>(Some(A)) {
Ok(Some(A)) => println!(),
Err(_) | Ok(None | Some(_)) => {},
}

match &Some(A) {
Some(A | B | C) => println!(),
None => {},
}

match &Some(A) {
&Some(A | B | C) => println!(),
None => {},
}

match &Some(A) {
Some(A | B) => println!(),
None | Some(_) => {},
}
}
20 changes: 19 additions & 1 deletion tests/ui/single_match.stderr
Original file line number Diff line number Diff line change
@@ -198,5 +198,23 @@ LL + }
LL + }
|

error: aborting due to 18 previous errors
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> tests/ui/single_match.rs:343:5
|
LL | / match Ok::<_, u32>(Some(A)) {
LL | | Ok(Some(A)) => println!(),
LL | | Err(_) | Ok(None | Some(_)) => {},
LL | | }
| |_____^ help: try: `if let Ok(Some(A)) = Ok::<_, u32>(Some(A)) { println!() }`

error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> tests/ui/single_match.rs:358:5
|
LL | / match &Some(A) {
LL | | Some(A | B) => println!(),
LL | | None | Some(_) => {},
LL | | }
| |_____^ help: try: `if let Some(A | B) = &Some(A) { println!() }`

error: aborting due to 20 previous errors

2 changes: 1 addition & 1 deletion tests/ui/unneeded_field_pattern.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@aux-build:proc_macros.rs
#![warn(clippy::unneeded_field_pattern)]
#![allow(dead_code, unused)]
#![allow(dead_code, unused, clippy::single_match)]

#[macro_use]
extern crate proc_macros;