Do not lint in macros for match lints

This commit is contained in:
ThibsG 2020-03-27 20:36:00 +01:00
parent 1765c5da90
commit 7fb94c2ac9
9 changed files with 119 additions and 17 deletions

View file

@ -389,6 +389,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches {
fn check_local(&mut self, cx: &LateContext<'a, 'tcx>, local: &'tcx Local<'_>) {
if_chain! {
if !in_external_macro(cx.sess(), local.span);
if !in_macro(local.span);
if let Some(ref expr) = local.init;
if let ExprKind::Match(ref target, ref arms, MatchSource::Normal) = expr.kind;
if arms.len() == 1 && arms[0].guard.is_none();
@ -423,6 +425,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches {
fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat<'_>) {
if_chain! {
if !in_external_macro(cx.sess(), pat.span);
if !in_macro(pat.span);
if let PatKind::Struct(ref qpath, fields, true) = pat.kind;
if let QPath::Resolved(_, ref path) = qpath;
if let Some(def_id) = path.res.opt_def_id();

View file

@ -11,12 +11,23 @@ struct TupleStruct(i32);
enum EmptyEnum {}
macro_rules! match_enum {
($param:expr) => {
let data = match $param {
SingleVariantEnum::Variant(i) => i,
};
};
}
fn infallible_destructuring_match_enum() {
let wrapper = SingleVariantEnum::Variant(0);
// This should lint!
let SingleVariantEnum::Variant(data) = wrapper;
// This shouldn't (inside macro)
match_enum!(wrapper);
// This shouldn't!
let data = match wrapper {
SingleVariantEnum::Variant(_) => -1,
@ -30,12 +41,23 @@ fn infallible_destructuring_match_enum() {
let SingleVariantEnum::Variant(data) = wrapper;
}
macro_rules! match_struct {
($param:expr) => {
let data = match $param {
TupleStruct(i) => i,
};
};
}
fn infallible_destructuring_match_struct() {
let wrapper = TupleStruct(0);
// This should lint!
let TupleStruct(data) = wrapper;
// This shouldn't (inside macro)
match_struct!(wrapper);
// This shouldn't!
let data = match wrapper {
TupleStruct(_) => -1,
@ -49,12 +71,23 @@ fn infallible_destructuring_match_struct() {
let TupleStruct(data) = wrapper;
}
macro_rules! match_never_enum {
($param:expr) => {
let data = match $param {
Ok(i) => i,
};
};
}
fn never_enum() {
let wrapper: Result<i32, !> = Ok(23);
// This should lint!
let Ok(data) = wrapper;
// This shouldn't (inside macro)
match_never_enum!(wrapper);
// This shouldn't!
let data = match wrapper {
Ok(_) => -1,

View file

@ -11,6 +11,14 @@ struct TupleStruct(i32);
enum EmptyEnum {}
macro_rules! match_enum {
($param:expr) => {
let data = match $param {
SingleVariantEnum::Variant(i) => i,
};
};
}
fn infallible_destructuring_match_enum() {
let wrapper = SingleVariantEnum::Variant(0);
@ -19,6 +27,9 @@ fn infallible_destructuring_match_enum() {
SingleVariantEnum::Variant(i) => i,
};
// This shouldn't (inside macro)
match_enum!(wrapper);
// This shouldn't!
let data = match wrapper {
SingleVariantEnum::Variant(_) => -1,
@ -32,6 +43,14 @@ fn infallible_destructuring_match_enum() {
let SingleVariantEnum::Variant(data) = wrapper;
}
macro_rules! match_struct {
($param:expr) => {
let data = match $param {
TupleStruct(i) => i,
};
};
}
fn infallible_destructuring_match_struct() {
let wrapper = TupleStruct(0);
@ -40,6 +59,9 @@ fn infallible_destructuring_match_struct() {
TupleStruct(i) => i,
};
// This shouldn't (inside macro)
match_struct!(wrapper);
// This shouldn't!
let data = match wrapper {
TupleStruct(_) => -1,
@ -53,6 +75,14 @@ fn infallible_destructuring_match_struct() {
let TupleStruct(data) = wrapper;
}
macro_rules! match_never_enum {
($param:expr) => {
let data = match $param {
Ok(i) => i,
};
};
}
fn never_enum() {
let wrapper: Result<i32, !> = Ok(23);
@ -61,6 +91,9 @@ fn never_enum() {
Ok(i) => i,
};
// This shouldn't (inside macro)
match_never_enum!(wrapper);
// This shouldn't!
let data = match wrapper {
Ok(_) => -1,

View file

@ -1,5 +1,5 @@
error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
--> $DIR/infallible_destructuring_match.rs:18:5
--> $DIR/infallible_destructuring_match.rs:26:5
|
LL | / let data = match wrapper {
LL | | SingleVariantEnum::Variant(i) => i,
@ -9,7 +9,7 @@ LL | | };
= note: `-D clippy::infallible-destructuring-match` implied by `-D warnings`
error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
--> $DIR/infallible_destructuring_match.rs:39:5
--> $DIR/infallible_destructuring_match.rs:58:5
|
LL | / let data = match wrapper {
LL | | TupleStruct(i) => i,
@ -17,7 +17,7 @@ LL | | };
| |______^ help: try this: `let TupleStruct(data) = wrapper;`
error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
--> $DIR/infallible_destructuring_match.rs:60:5
--> $DIR/infallible_destructuring_match.rs:90:5
|
LL | / let data = match wrapper {
LL | | Ok(i) => i,

View file

@ -12,6 +12,14 @@ fn coords() -> Point {
Point { x: 1, y: 2 }
}
macro_rules! foo {
($param:expr) => {
match $param {
_ => println!("whatever"),
}
};
}
fn main() {
let a = 1;
let b = 2;
@ -25,6 +33,8 @@ fn main() {
let (x, y, z) = (a, b, c);
println!("{} {} {}", x, y, z);
// Ok
foo!(a);
// Ok
match a {
2 => println!("2"),
_ => println!("Not 2"),

View file

@ -12,6 +12,14 @@ fn coords() -> Point {
Point { x: 1, y: 2 }
}
macro_rules! foo {
($param:expr) => {
match $param {
_ => println!("whatever"),
}
};
}
fn main() {
let a = 1;
let b = 2;
@ -27,6 +35,8 @@ fn main() {
(x, y, z) => println!("{} {} {}", x, y, z),
}
// Ok
foo!(a);
// Ok
match a {
2 => println!("2"),
_ => println!("Not 2"),

View file

@ -1,5 +1,5 @@
error: this match could be written as a `let` statement
--> $DIR/match_single_binding.rs:20:5
--> $DIR/match_single_binding.rs:28:5
|
LL | / match (a, b, c) {
LL | | (x, y, z) => {
@ -18,7 +18,7 @@ LL | }
|
error: this match could be written as a `let` statement
--> $DIR/match_single_binding.rs:26:5
--> $DIR/match_single_binding.rs:34:5
|
LL | / match (a, b, c) {
LL | | (x, y, z) => println!("{} {} {}", x, y, z),
@ -32,7 +32,7 @@ LL | println!("{} {} {}", x, y, z);
|
error: this match could be replaced by its body itself
--> $DIR/match_single_binding.rs:41:5
--> $DIR/match_single_binding.rs:51:5
|
LL | / match a {
LL | | _ => println!("whatever"),
@ -40,7 +40,7 @@ LL | | }
| |_____^ help: consider using the match body instead: `println!("whatever");`
error: this match could be replaced by its body itself
--> $DIR/match_single_binding.rs:45:5
--> $DIR/match_single_binding.rs:55:5
|
LL | / match a {
LL | | _ => {
@ -59,7 +59,7 @@ LL | }
|
error: this match could be replaced by its body itself
--> $DIR/match_single_binding.rs:52:5
--> $DIR/match_single_binding.rs:62:5
|
LL | / match a {
LL | | _ => {
@ -81,7 +81,7 @@ LL | }
|
error: this match could be written as a `let` statement
--> $DIR/match_single_binding.rs:62:5
--> $DIR/match_single_binding.rs:72:5
|
LL | / match p {
LL | | Point { x, y } => println!("Coords: ({}, {})", x, y),
@ -95,7 +95,7 @@ LL | println!("Coords: ({}, {})", x, y);
|
error: this match could be written as a `let` statement
--> $DIR/match_single_binding.rs:66:5
--> $DIR/match_single_binding.rs:76:5
|
LL | / match p {
LL | | Point { x: x1, y: y1 } => println!("Coords: ({}, {})", x1, y1),
@ -109,7 +109,7 @@ LL | println!("Coords: ({}, {})", x1, y1);
|
error: this match could be written as a `let` statement
--> $DIR/match_single_binding.rs:71:5
--> $DIR/match_single_binding.rs:81:5
|
LL | / match x {
LL | | ref r => println!("Got a reference to {}", r),
@ -123,7 +123,7 @@ LL | println!("Got a reference to {}", r);
|
error: this match could be written as a `let` statement
--> $DIR/match_single_binding.rs:76:5
--> $DIR/match_single_binding.rs:86:5
|
LL | / match x {
LL | | ref mut mr => println!("Got a mutable reference to {}", mr),
@ -137,7 +137,7 @@ LL | println!("Got a mutable reference to {}", mr);
|
error: this match could be written as a `let` statement
--> $DIR/match_single_binding.rs:80:5
--> $DIR/match_single_binding.rs:90:5
|
LL | / let product = match coords() {
LL | | Point { x, y } => x * y,
@ -151,7 +151,7 @@ LL | let product = x * y;
|
error: this match could be written as a `let` statement
--> $DIR/match_single_binding.rs:88:18
--> $DIR/match_single_binding.rs:98:18
|
LL | .map(|i| match i.unwrap() {
| __________________^

View file

@ -6,6 +6,15 @@ struct A {
c: &'static str,
}
macro_rules! foo {
($param:expr) => {
match $param {
A { a: 0, b: 0, c: "", .. } => {},
_ => {},
}
};
}
fn main() {
let a_struct = A { a: 5, b: 42, c: "A" };
@ -27,4 +36,7 @@ fn main() {
A { a: 0, b: 0, .. } => {},
_ => {},
}
// No lint
foo!(a_struct);
}

View file

@ -1,5 +1,5 @@
error: unnecessary use of `..` pattern in struct binding. All fields were already bound
--> $DIR/rest_pat_in_fully_bound_structs.rs:13:9
--> $DIR/rest_pat_in_fully_bound_structs.rs:22:9
|
LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint
= help: consider removing `..` from this binding
error: unnecessary use of `..` pattern in struct binding. All fields were already bound
--> $DIR/rest_pat_in_fully_bound_structs.rs:14:9
--> $DIR/rest_pat_in_fully_bound_structs.rs:23:9
|
LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -16,7 +16,7 @@ LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint
= help: consider removing `..` from this binding
error: unnecessary use of `..` pattern in struct binding. All fields were already bound
--> $DIR/rest_pat_in_fully_bound_structs.rs:20:9
--> $DIR/rest_pat_in_fully_bound_structs.rs:29:9
|
LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^