Skip to content

Commit c771204

Browse files
committed
Auto merge of #13456 - vHugoObject:master, r=llogiq
fix(clippy_lints/matches): wildcard_in_or_patterns will no longer be triggered for types annotated with #[nonexhaustive] fixes #13350 ---- changelog: none
2 parents 2a61f59 + bc07027 commit c771204

File tree

4 files changed

+97
-5
lines changed

4 files changed

+97
-5
lines changed

clippy_lints/src/matches/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
10451045
if !from_expansion {
10461046
// These don't depend on a relationship between multiple arms
10471047
match_wild_err_arm::check(cx, ex, arms);
1048-
wild_in_or_pats::check(cx, arms);
1048+
wild_in_or_pats::check(cx, ex, arms);
10491049
}
10501050

10511051
if let MatchSource::TryDesugar(_) = source {

clippy_lints/src/matches/wild_in_or_pats.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
use clippy_utils::diagnostics::span_lint_and_help;
2-
use clippy_utils::is_wild;
3-
use rustc_hir::{Arm, PatKind};
2+
use clippy_utils::{has_non_exhaustive_attr, is_wild};
3+
use rustc_hir::{Arm, Expr, PatKind};
44
use rustc_lint::LateContext;
5+
use rustc_middle::ty;
56

67
use super::WILDCARD_IN_OR_PATTERNS;
78

8-
pub(crate) fn check(cx: &LateContext<'_>, arms: &[Arm<'_>]) {
9+
pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arms: &[Arm<'_>]) {
10+
// first check if we are matching on an enum that has the non_exhaustive attribute
11+
let ty = cx.typeck_results().expr_ty(expr).peel_refs();
12+
if let ty::Adt(adt_def, _) = ty.kind()
13+
&& has_non_exhaustive_attr(cx.tcx, *adt_def)
14+
{
15+
return;
16+
};
917
for arm in arms {
1018
if let PatKind::Or(fields) = arm.pat.kind {
1119
// look for multiple fields in this arm that contains at least one Wild pattern

tests/ui/wild_in_or_pats.rs

+68
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,72 @@ fn main() {
3737
dbg!("matched (bar or) wild");
3838
},
3939
};
40+
41+
// shouldn't lint
42+
#[non_exhaustive]
43+
pub enum NonExhaustiveEnum<'a> {
44+
Message(&'a str),
45+
Quit(&'a str),
46+
Other,
47+
}
48+
49+
match NonExhaustiveEnum::Message("Pass") {
50+
NonExhaustiveEnum::Message(_) => dbg!("message"),
51+
NonExhaustiveEnum::Quit(_) => dbg!("quit"),
52+
NonExhaustiveEnum::Other | _ => dbg!("wildcard"),
53+
};
54+
55+
// should lint
56+
enum ExhaustiveEnum {
57+
Quit,
58+
Write(String),
59+
ChangeColor(i32, i32, i32),
60+
}
61+
62+
match ExhaustiveEnum::ChangeColor(0, 160, 255) {
63+
ExhaustiveEnum::Write(text) => {
64+
dbg!("Write");
65+
},
66+
ExhaustiveEnum::ChangeColor(r, g, b) => {
67+
dbg!("Change the color");
68+
},
69+
ExhaustiveEnum::Quit | _ => {
70+
dbg!("Quit or other");
71+
},
72+
};
73+
74+
// shouldn't lint
75+
#[non_exhaustive]
76+
struct NonExhaustiveStruct {
77+
a: u32,
78+
b: u32,
79+
c: u64,
80+
}
81+
82+
let b = NonExhaustiveStruct { a: 5, b: 42, c: 342 };
83+
84+
match b {
85+
NonExhaustiveStruct { a: 5, b: 42, .. } => {},
86+
NonExhaustiveStruct { a: 0, b: 0, c: 128 } => {},
87+
NonExhaustiveStruct { a: 0, b: 0, c: 128, .. } | _ => {},
88+
}
89+
90+
// should lint
91+
struct ExhaustiveStruct {
92+
x: i32,
93+
y: i32,
94+
}
95+
96+
let p = ExhaustiveStruct { x: 0, y: 7 };
97+
match p {
98+
ExhaustiveStruct { x: 0, y: 0 } => {
99+
dbg!("On the x axis at {x}");
100+
},
101+
ExhaustiveStruct { x: 0, y: 1 } => {
102+
dbg!("On the y axis at {y}");
103+
},
104+
ExhaustiveStruct { x: 1, y: 1 } | _ => {
105+
dbg!("On neither axis: ({x}, {y})");
106+
},
107+
}
40108
}

tests/ui/wild_in_or_pats.stderr

+17-1
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,21 @@ LL | _ | "bar" => {
3232
|
3333
= help: consider handling `_` separately
3434

35-
error: aborting due to 4 previous errors
35+
error: wildcard pattern covers any other pattern as it will match anyway
36+
--> tests/ui/wild_in_or_pats.rs:69:9
37+
|
38+
LL | ExhaustiveEnum::Quit | _ => {
39+
| ^^^^^^^^^^^^^^^^^^^^^^^^
40+
|
41+
= help: consider handling `_` separately
42+
43+
error: wildcard pattern covers any other pattern as it will match anyway
44+
--> tests/ui/wild_in_or_pats.rs:104:9
45+
|
46+
LL | ExhaustiveStruct { x: 1, y: 1 } | _ => {
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
48+
|
49+
= help: consider handling `_` separately
50+
51+
error: aborting due to 6 previous errors
3652

0 commit comments

Comments
 (0)