fix(equatable_if_let): don't lint if pattern or initializer come from expansion
This commit is contained in:
parent
2193494b6c
commit
db4adbdccc
4 changed files with 157 additions and 41 deletions
|
|
@ -106,6 +106,8 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
|
|||
if let ExprKind::Let(let_expr) = expr.kind
|
||||
&& is_unary_pattern(let_expr.pat)
|
||||
&& !expr.span.in_external_macro(cx.sess().source_map())
|
||||
&& !let_expr.pat.span.from_expansion()
|
||||
&& !let_expr.init.span.from_expansion()
|
||||
{
|
||||
let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
|
||||
let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ impl PartialEq for NotStructuralEq {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline_macros]
|
||||
fn main() {
|
||||
let a = 2;
|
||||
let b = 3;
|
||||
|
|
@ -87,13 +86,6 @@ fn main() {
|
|||
//~^ equatable_if_let
|
||||
if matches!(h, NoPartialEqStruct { a: 2, b: false }) {}
|
||||
//~^ equatable_if_let
|
||||
|
||||
if "abc" == inline!("abc") {
|
||||
//~^ equatable_if_let
|
||||
println!("OK");
|
||||
}
|
||||
|
||||
external!({ if let 2 = $a {} });
|
||||
}
|
||||
|
||||
mod issue8710 {
|
||||
|
|
@ -132,6 +124,74 @@ mod issue8710 {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline_macros]
|
||||
fn issue14548() {
|
||||
if let inline!("abc") = "abc" {
|
||||
println!("OK");
|
||||
}
|
||||
|
||||
let a = 2;
|
||||
external!({ if let 2 = $a {} });
|
||||
|
||||
// Don't lint: `==`/`matches!` might be correct for a particular `$($font)|*`, but not in general
|
||||
macro_rules! m1 {
|
||||
($($font:pat_param)|*) => {
|
||||
if let $($font)|* = "from_expansion" {}
|
||||
}
|
||||
}
|
||||
m1!("foo");
|
||||
m1!("Sans" | "Serif" | "Sans Mono");
|
||||
m1!(inline!("foo"));
|
||||
|
||||
// Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in
|
||||
// general
|
||||
macro_rules! m2 {
|
||||
($from_root_ctxt:pat) => {
|
||||
if let $from_root_ctxt = "from_expansion" {}
|
||||
};
|
||||
}
|
||||
m2!("foo");
|
||||
m2!("Sans" | "Serif" | "Sans Mono");
|
||||
m2!(inline!("foo"));
|
||||
|
||||
// Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in
|
||||
// general
|
||||
macro_rules! m3 {
|
||||
($from_root_ctxt:expr) => {
|
||||
if let "from_expansion" = $from_root_ctxt {}
|
||||
};
|
||||
}
|
||||
m3!("foo");
|
||||
m3!("foo");
|
||||
m3!(inline!("foo"));
|
||||
|
||||
// Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in
|
||||
// general. Don't get confused by the scrutinee coming from macro invocation
|
||||
macro_rules! m4 {
|
||||
($from_root_ctxt:pat) => {
|
||||
if let $from_root_ctxt = inline!("from_expansion") {}
|
||||
};
|
||||
}
|
||||
m4!("foo");
|
||||
m4!("Sans" | "Serif" | "Sans Mono");
|
||||
m4!(inline!("foo"));
|
||||
|
||||
// Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in
|
||||
// general. Don't get confused by the scrutinee coming from macro invocation
|
||||
macro_rules! m5 {
|
||||
($from_root_ctxt:expr) => {
|
||||
if let inline!("from_expansion") = $from_root_ctxt {}
|
||||
};
|
||||
}
|
||||
m5!("foo");
|
||||
m5!("foo");
|
||||
m5!(inline!("foo"));
|
||||
|
||||
// Would be nice to lint: both sides are macro _invocations_, so the suggestion is correct in
|
||||
// general
|
||||
if let inline!("foo") = inline!("bar") {}
|
||||
}
|
||||
|
||||
// PartialEq is not stable in consts yet
|
||||
fn issue15376() {
|
||||
enum NonConstEq {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ impl PartialEq for NotStructuralEq {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline_macros]
|
||||
fn main() {
|
||||
let a = 2;
|
||||
let b = 3;
|
||||
|
|
@ -87,13 +86,6 @@ fn main() {
|
|||
//~^ equatable_if_let
|
||||
if let NoPartialEqStruct { a: 2, b: false } = h {}
|
||||
//~^ equatable_if_let
|
||||
|
||||
if let inline!("abc") = "abc" {
|
||||
//~^ equatable_if_let
|
||||
println!("OK");
|
||||
}
|
||||
|
||||
external!({ if let 2 = $a {} });
|
||||
}
|
||||
|
||||
mod issue8710 {
|
||||
|
|
@ -132,6 +124,74 @@ mod issue8710 {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline_macros]
|
||||
fn issue14548() {
|
||||
if let inline!("abc") = "abc" {
|
||||
println!("OK");
|
||||
}
|
||||
|
||||
let a = 2;
|
||||
external!({ if let 2 = $a {} });
|
||||
|
||||
// Don't lint: `==`/`matches!` might be correct for a particular `$($font)|*`, but not in general
|
||||
macro_rules! m1 {
|
||||
($($font:pat_param)|*) => {
|
||||
if let $($font)|* = "from_expansion" {}
|
||||
}
|
||||
}
|
||||
m1!("foo");
|
||||
m1!("Sans" | "Serif" | "Sans Mono");
|
||||
m1!(inline!("foo"));
|
||||
|
||||
// Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in
|
||||
// general
|
||||
macro_rules! m2 {
|
||||
($from_root_ctxt:pat) => {
|
||||
if let $from_root_ctxt = "from_expansion" {}
|
||||
};
|
||||
}
|
||||
m2!("foo");
|
||||
m2!("Sans" | "Serif" | "Sans Mono");
|
||||
m2!(inline!("foo"));
|
||||
|
||||
// Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in
|
||||
// general
|
||||
macro_rules! m3 {
|
||||
($from_root_ctxt:expr) => {
|
||||
if let "from_expansion" = $from_root_ctxt {}
|
||||
};
|
||||
}
|
||||
m3!("foo");
|
||||
m3!("foo");
|
||||
m3!(inline!("foo"));
|
||||
|
||||
// Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in
|
||||
// general. Don't get confused by the scrutinee coming from macro invocation
|
||||
macro_rules! m4 {
|
||||
($from_root_ctxt:pat) => {
|
||||
if let $from_root_ctxt = inline!("from_expansion") {}
|
||||
};
|
||||
}
|
||||
m4!("foo");
|
||||
m4!("Sans" | "Serif" | "Sans Mono");
|
||||
m4!(inline!("foo"));
|
||||
|
||||
// Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in
|
||||
// general. Don't get confused by the scrutinee coming from macro invocation
|
||||
macro_rules! m5 {
|
||||
($from_root_ctxt:expr) => {
|
||||
if let inline!("from_expansion") = $from_root_ctxt {}
|
||||
};
|
||||
}
|
||||
m5!("foo");
|
||||
m5!("foo");
|
||||
m5!(inline!("foo"));
|
||||
|
||||
// Would be nice to lint: both sides are macro _invocations_, so the suggestion is correct in
|
||||
// general
|
||||
if let inline!("foo") = inline!("bar") {}
|
||||
}
|
||||
|
||||
// PartialEq is not stable in consts yet
|
||||
fn issue15376() {
|
||||
enum NonConstEq {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:56:8
|
||||
--> tests/ui/equatable_if_let.rs:55:8
|
||||
|
|
||||
LL | if let 2 = a {}
|
||||
| ^^^^^^^^^ help: try: `a == 2`
|
||||
|
|
@ -8,112 +8,106 @@ LL | if let 2 = a {}
|
|||
= help: to override `-D warnings` add `#[allow(clippy::equatable_if_let)]`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:58:8
|
||||
--> tests/ui/equatable_if_let.rs:57:8
|
||||
|
|
||||
LL | if let Ordering::Greater = a.cmp(&b) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:60:8
|
||||
--> tests/ui/equatable_if_let.rs:59:8
|
||||
|
|
||||
LL | if let Some(2) = c {}
|
||||
| ^^^^^^^^^^^^^^^ help: try: `c == Some(2)`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:62:8
|
||||
--> tests/ui/equatable_if_let.rs:61:8
|
||||
|
|
||||
LL | if let Struct { a: 2, b: false } = d {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:64:8
|
||||
--> tests/ui/equatable_if_let.rs:63:8
|
||||
|
|
||||
LL | if let Enum::TupleVariant(32, 64) = e {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:66:8
|
||||
--> tests/ui/equatable_if_let.rs:65:8
|
||||
|
|
||||
LL | if let Enum::RecordVariant { a: 64, b: 32 } = e {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:68:8
|
||||
--> tests/ui/equatable_if_let.rs:67:8
|
||||
|
|
||||
LL | if let Enum::UnitVariant = e {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:70:8
|
||||
--> tests/ui/equatable_if_let.rs:69:8
|
||||
|
|
||||
LL | if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })`
|
||||
|
||||
error: this pattern matching can be expressed using `matches!`
|
||||
--> tests/ui/equatable_if_let.rs:80:8
|
||||
--> tests/ui/equatable_if_let.rs:79:8
|
||||
|
|
||||
LL | if let NotPartialEq::A = f {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:82:8
|
||||
--> tests/ui/equatable_if_let.rs:81:8
|
||||
|
|
||||
LL | if let NotStructuralEq::A = g {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A`
|
||||
|
||||
error: this pattern matching can be expressed using `matches!`
|
||||
--> tests/ui/equatable_if_let.rs:84:8
|
||||
--> tests/ui/equatable_if_let.rs:83:8
|
||||
|
|
||||
LL | if let Some(NotPartialEq::A) = Some(f) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:86:8
|
||||
--> tests/ui/equatable_if_let.rs:85:8
|
||||
|
|
||||
LL | if let Some(NotStructuralEq::A) = Some(g) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)`
|
||||
|
||||
error: this pattern matching can be expressed using `matches!`
|
||||
--> tests/ui/equatable_if_let.rs:88:8
|
||||
--> tests/ui/equatable_if_let.rs:87:8
|
||||
|
|
||||
LL | if let NoPartialEqStruct { a: 2, b: false } = h {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })`
|
||||
|
||||
error: this pattern matching can be expressed using equality
|
||||
--> tests/ui/equatable_if_let.rs:91:8
|
||||
|
|
||||
LL | if let inline!("abc") = "abc" {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"abc" == inline!("abc")`
|
||||
|
||||
error: this pattern matching can be expressed using `matches!`
|
||||
--> tests/ui/equatable_if_let.rs:101:12
|
||||
--> tests/ui/equatable_if_let.rs:93:12
|
||||
|
|
||||
LL | if let Some('i') = cs.iter().next() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(cs.iter().next(), Some('i'))`
|
||||
|
||||
error: this pattern matching can be expressed using `matches!`
|
||||
--> tests/ui/equatable_if_let.rs:109:12
|
||||
--> tests/ui/equatable_if_let.rs:101:12
|
||||
|
|
||||
LL | if let Some(1) = cs.iter().next() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(cs.iter().next(), Some(1))`
|
||||
|
||||
error: this pattern matching can be expressed using `matches!`
|
||||
--> tests/ui/equatable_if_let.rs:127:12
|
||||
--> tests/ui/equatable_if_let.rs:119:12
|
||||
|
|
||||
LL | if let Some(MyEnum::B) = get_enum() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(get_enum(), Some(MyEnum::B))`
|
||||
|
||||
error: this pattern matching can be expressed using `matches!`
|
||||
--> tests/ui/equatable_if_let.rs:158:23
|
||||
--> tests/ui/equatable_if_let.rs:210:23
|
||||
|
|
||||
LL | const _: u32 = if let NonConstEq::A = N { 0 } else { 1 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(N, NonConstEq::A)`
|
||||
|
||||
error: this pattern matching can be expressed using `matches!`
|
||||
--> tests/ui/equatable_if_let.rs:160:23
|
||||
--> tests/ui/equatable_if_let.rs:212:23
|
||||
|
|
||||
LL | const _: u32 = if let Some(NonConstEq::A) = Some(N) { 0 } else { 1 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(N), Some(NonConstEq::A))`
|
||||
|
||||
error: aborting due to 19 previous errors
|
||||
error: aborting due to 18 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue