diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs index 0cbaee9cc83e..82ef50a58ce5 100644 --- a/clippy_lints/src/equatable_if_let.rs +++ b/clippy_lints/src/equatable_if_let.rs @@ -9,9 +9,11 @@ use rustc_hir::{ }; use rustc_lint::{LateContext, LateLintPass, Lint}; use rustc_middle::ty::{Adt, Ty}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::Span; +use crate::utils::conf::EquatablePatternLevel; + declare_clippy_lint! { /// ### What it does /// Checks for `if let = ` (and `while let` and similars) that can be expressed @@ -64,7 +66,17 @@ declare_clippy_lint! { "using `matches!` instead of equality" } -declare_lint_pass!(PatternEquality => [EQUATABLE_IF_LET, EQUATABLE_MATCHES]); +pub struct PatternEquality { + level: EquatablePatternLevel, +} + +impl PatternEquality { + pub fn new(level: EquatablePatternLevel) -> PatternEquality { + PatternEquality { level } + } +} + +impl_lint_pass!(PatternEquality => [EQUATABLE_IF_LET, EQUATABLE_MATCHES]); fn equatable_pattern(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { fn array_rec(cx: &LateContext<'_>, pats: &[Pat<'_>]) -> bool { @@ -179,21 +191,30 @@ fn pat_to_string(cx: &LateContext<'tcx>, app: &mut Applicability, pat: &Pat<'_>, Some(r) } -fn emit_lint(cx: &LateContext<'tcx>, pat: &Pat<'_>, exp: &Expr<'_>, span: Span, lint: &'static Lint) { +fn level_contains(level: EquatablePatternLevel, pat: &Pat<'_>) -> bool { + match level { + EquatablePatternLevel::Primitive => matches!(pat.kind, PatKind::Lit(_)), + EquatablePatternLevel::Simple => matches!(pat.kind, PatKind::Lit(_) | PatKind::Path(_)), + EquatablePatternLevel::All => true, + } +} + +fn emit_lint( + cx: &LateContext<'tcx>, + pat: &Pat<'_>, + exp: &Expr<'_>, + span: Span, + lint: &'static Lint, + level: EquatablePatternLevel, +) { if_chain! { if equatable_pattern(cx, pat); + if level_contains(level, pat); let exp_ty = cx.typeck_results().expr_ty(exp); if is_partial_eq(cx, exp_ty, exp_ty); let mut app = Applicability::MachineApplicable; if let Some(pat_str) = pat_to_string(cx, &mut app, pat, exp_ty); then { - /*let pat_str = match pat.kind { - PatKind::Struct(..) => format!( - "({})", - snippet_with_applicability(cx, pat.span, "..", &mut applicability), - ), - _ => snippet_with_applicability(cx, pat.span, "..", &mut applicability).to_string(), - };*/ let exp_str = snippet_with_applicability(cx, exp.span, "..", &mut app); span_lint_and_sugg( cx, @@ -215,7 +236,7 @@ fn emit_lint(cx: &LateContext<'tcx>, pat: &Pat<'_>, exp: &Expr<'_>, span: Span, impl<'tcx> LateLintPass<'tcx> for PatternEquality { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if let ExprKind::Let(pat, exp, _) = expr.kind { - emit_lint(cx, pat, exp, expr.span, EQUATABLE_IF_LET); + emit_lint(cx, pat, exp, expr.span, EQUATABLE_IF_LET, self.level); } if let Some(MatchesExpn { call_site, @@ -223,7 +244,7 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality { exp, }) = MatchesExpn::parse(expr) { - emit_lint(cx, pat, exp, call_site, EQUATABLE_MATCHES); + emit_lint(cx, pat, exp, call_site, EQUATABLE_MATCHES, self.level); } } } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index c2376575cb81..5c062d409708 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -721,7 +721,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| Box::new(option_if_let_else::OptionIfLetElse)); store.register_late_pass(|| Box::new(future_not_send::FutureNotSend)); store.register_late_pass(|| Box::new(if_let_mutex::IfLetMutex)); - store.register_late_pass(|| Box::new(equatable_if_let::PatternEquality)); + let equatable_pattern = conf.equatable_pattern; + store.register_late_pass(move || Box::new(equatable_if_let::PatternEquality::new(equatable_pattern))); store.register_late_pass(|| Box::new(mut_mutex_lock::MutMutexLock)); store.register_late_pass(|| Box::new(match_on_vec_items::MatchOnVecItems)); store.register_late_pass(|| Box::new(manual_async_fn::ManualAsyncFn)); diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 6cbada4c1505..a433490f73e8 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -15,6 +15,13 @@ pub struct Rename { pub rename: String, } +#[derive(Clone, Copy, Debug, Deserialize)] +pub enum EquatablePatternLevel { + Primitive, + Simple, + All, +} + /// A single disallowed method, used by the `DISALLOWED_METHOD` lint. #[derive(Clone, Debug, Deserialize)] #[serde(untagged)] @@ -288,6 +295,10 @@ define_Conf! { /// /// Whether to apply the raw pointer heuristic to determine if a type is `Send`. (enable_raw_pointer_heuristic_for_send: bool = true), + /// Lint: EQUATABLE_IF_LET, EQUATABLE_MATCHES + /// + /// Whether to detect pattern as a value for using with equality. + (equatable_pattern: crate::utils::conf::EquatablePatternLevel = crate::utils::conf::EquatablePatternLevel::Simple), } /// Search for the configuration file. diff --git a/tests/ui-toml/equatable_pattern/all.fixed b/tests/ui-toml/equatable_pattern/all.fixed new file mode 100644 index 000000000000..053667e82133 --- /dev/null +++ b/tests/ui-toml/equatable_pattern/all.fixed @@ -0,0 +1,130 @@ +// run-rustfix + +#![allow(unused_variables, dead_code, clippy::redundant_pattern_matching, clippy::op_ref)] +#![warn(clippy::equatable_if_let, clippy::equatable_matches)] + +use std::cmp::Ordering; + +#[derive(PartialEq)] +enum Enum { + TupleVariant(i32, u64), + RecordVariant { a: i64, b: u32 }, + UnitVariant, + Recursive(Struct), +} + +#[derive(PartialEq)] +struct Struct { + a: i32, + b: bool, +} + +#[derive(Clone, Copy)] +enum NotPartialEq { + A, + B, +} + +#[derive(Clone, Copy)] +enum NotStructuralEq { + A, + B, +} + +impl PartialEq for NotStructuralEq { + fn eq(&self, _: &NotStructuralEq) -> bool { + false + } +} + +#[derive(PartialEq)] +enum Generic { + VA(A), + VB(B), + VC, +} + +#[derive(PartialEq)] +struct Generic2 { + a: A, + b: B, +} + +fn main() { + let a = 2; + let b = 3; + let c = Some(2); + let d = Struct { a: 2, b: false }; + let e = Enum::UnitVariant; + let f = NotPartialEq::A; + let g = NotStructuralEq::A; + let h: Generic = Generic::VC; + let i: Generic = Generic::VC; + let j = vec![1, 2, 3, 4]; + let k = Some(&false); + let l = Generic2 { + a: Generic2 { a: "xxxx", b: 3 }, + b: Generic2 { + a: &Enum::UnitVariant, + b: false, + }, + }; + let m = Generic2 { a: 3, b: 5 }; + let n = Some("xxxx"); + let mut o = j.iter(); + + // true + + if a == 2 {} + if a.cmp(&b) == Ordering::Greater {} + if c == Some(2) {} + if d == (Struct { a: 2, b: false }) {} + if e == Enum::TupleVariant(32, 64) {} + if e == (Enum::RecordVariant { a: 64, b: 32 }) {} + if e == Enum::UnitVariant {} + if (e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false }) {} + if Some(g) == None {} + if i == Generic::VA(Enum::UnitVariant) {} + if i == Generic::VC {} + if j[1..3] == [7, 5] {} + if j[..] == [1, 2, 3, 4] {} + if k == Some(&true) {} + if k == Some(&false) {} + if &k == &Some(&true) {} + if &&k == &&Some(&false) {} + if k == None {} + if l == (Generic2 { a: Generic2 { a: "yyy", b: 3 }, b: Generic2 { a: &Enum::UnitVariant, b: false } }) + {} + if m == (Generic2 { a: 3, b: 5 }) {} + if n == Some("yyy") {} + + let _ = c == Some(2); + + while o.next() == Some(&2) {} + + // false + + if let 2 | 3 = a {} + if let x @ 2 = a {} + if let Some(3 | 4) = c {} + if let Struct { a, b: false } = d {} + if let Struct { a: 2, b: x } = d {} + if let NotPartialEq::A = f {} + if let NotStructuralEq::A = g {} + if let Some(NotPartialEq::A) = Some(f) {} + if let None = Some(f) {} + if let Some(NotStructuralEq::A) = Some(g) {} + if let Generic::VA(Enum::UnitVariant) = h {} + if let Generic::VB(NotPartialEq::A) = h {} + if let Generic::VC = h {} + if let Generic::VB(NotStructuralEq::A) = i {} + if let [7, _] = j[2..] {} + if let [1, 2 | 5, 3, 4] = j[..] {} + if let [2, ..] = j[..] {} + + let _ = matches!(c, Some(x)); + let _ = matches!(c, Some(x) if x == 2); + let _ = matches!(c, Some(2) if 3 > 5); + + while let Some(4 | 7) = o.next() {} +} diff --git a/tests/ui-toml/equatable_pattern/all.rs b/tests/ui-toml/equatable_pattern/all.rs new file mode 100644 index 000000000000..7c2d8cf9d919 --- /dev/null +++ b/tests/ui-toml/equatable_pattern/all.rs @@ -0,0 +1,136 @@ +// run-rustfix + +#![allow(unused_variables, dead_code, clippy::redundant_pattern_matching, clippy::op_ref)] +#![warn(clippy::equatable_if_let, clippy::equatable_matches)] + +use std::cmp::Ordering; + +#[derive(PartialEq)] +enum Enum { + TupleVariant(i32, u64), + RecordVariant { a: i64, b: u32 }, + UnitVariant, + Recursive(Struct), +} + +#[derive(PartialEq)] +struct Struct { + a: i32, + b: bool, +} + +#[derive(Clone, Copy)] +enum NotPartialEq { + A, + B, +} + +#[derive(Clone, Copy)] +enum NotStructuralEq { + A, + B, +} + +impl PartialEq for NotStructuralEq { + fn eq(&self, _: &NotStructuralEq) -> bool { + false + } +} + +#[derive(PartialEq)] +enum Generic { + VA(A), + VB(B), + VC, +} + +#[derive(PartialEq)] +struct Generic2 { + a: A, + b: B, +} + +fn main() { + let a = 2; + let b = 3; + let c = Some(2); + let d = Struct { a: 2, b: false }; + let e = Enum::UnitVariant; + let f = NotPartialEq::A; + let g = NotStructuralEq::A; + let h: Generic = Generic::VC; + let i: Generic = Generic::VC; + let j = vec![1, 2, 3, 4]; + let k = Some(&false); + let l = Generic2 { + a: Generic2 { a: "xxxx", b: 3 }, + b: Generic2 { + a: &Enum::UnitVariant, + b: false, + }, + }; + let m = Generic2 { a: 3, b: 5 }; + let n = Some("xxxx"); + let mut o = j.iter(); + + // true + + if let 2 = a {} + if let Ordering::Greater = a.cmp(&b) {} + if let Some(2) = c {} + if let Struct { a: 2, b: false } = d {} + if let Enum::TupleVariant(32, 64) = e {} + if let Enum::RecordVariant { a: 64, b: 32 } = e {} + if let Enum::UnitVariant = e {} + if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {} + if let None = Some(g) {} + if let Generic::VA(Enum::UnitVariant) = i {} + if let Generic::VC = i {} + if let [7, 5] = j[1..3] {} + if let [1, 2, 3, 4] = j[..] {} + if let Some(true) = k {} + if let Some(&false) = k {} + if let Some(true) = &k {} + if let Some(false) = &&k {} + if let None = k {} + if let Generic2 { + a: Generic2 { a: "yyy", b: 3 }, + b: Generic2 { + a: Enum::UnitVariant, + b: false, + }, + } = l + {} + if let Generic2 { a: 3, b: 5 } = m {} + if let Some("yyy") = n {} + + let _ = matches!(c, Some(2)); + + while let Some(2) = o.next() {} + + // false + + if let 2 | 3 = a {} + if let x @ 2 = a {} + if let Some(3 | 4) = c {} + if let Struct { a, b: false } = d {} + if let Struct { a: 2, b: x } = d {} + if let NotPartialEq::A = f {} + if let NotStructuralEq::A = g {} + if let Some(NotPartialEq::A) = Some(f) {} + if let None = Some(f) {} + if let Some(NotStructuralEq::A) = Some(g) {} + if let Generic::VA(Enum::UnitVariant) = h {} + if let Generic::VB(NotPartialEq::A) = h {} + if let Generic::VC = h {} + if let Generic::VB(NotStructuralEq::A) = i {} + if let [7, _] = j[2..] {} + if let [1, 2 | 5, 3, 4] = j[..] {} + if let [2, ..] = j[..] {} + + let _ = matches!(c, Some(x)); + let _ = matches!(c, Some(x) if x == 2); + let _ = matches!(c, Some(2) if 3 > 5); + + while let Some(4 | 7) = o.next() {} +} diff --git a/tests/ui-toml/equatable_pattern/all.stderr b/tests/ui-toml/equatable_pattern/all.stderr new file mode 100644 index 000000000000..f94fe3fac971 --- /dev/null +++ b/tests/ui-toml/equatable_pattern/all.stderr @@ -0,0 +1,151 @@ +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:78:8 + | +LL | if let 2 = a {} + | ^^^^^^^^^ help: try: `a == 2` + | + = note: `-D clippy::equatable-if-let` implied by `-D warnings` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:79: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 + --> $DIR/all.rs:80:8 + | +LL | if let Some(2) = c {} + | ^^^^^^^^^^^^^^^ help: try: `c == Some(2)` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:81: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 + --> $DIR/all.rs:82: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 + --> $DIR/all.rs:83: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 + --> $DIR/all.rs:84:8 + | +LL | if let Enum::UnitVariant = e {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:85: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 equality + --> $DIR/all.rs:86:8 + | +LL | if let None = Some(g) {} + | ^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == None` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:87:8 + | +LL | if let Generic::VA(Enum::UnitVariant) = i {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i == Generic::VA(Enum::UnitVariant)` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:88:8 + | +LL | if let Generic::VC = i {} + | ^^^^^^^^^^^^^^^^^^^ help: try: `i == Generic::VC` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:89:8 + | +LL | if let [7, 5] = j[1..3] {} + | ^^^^^^^^^^^^^^^^^^^^ help: try: `j[1..3] == [7, 5]` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:90:8 + | +LL | if let [1, 2, 3, 4] = j[..] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `j[..] == [1, 2, 3, 4]` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:91:8 + | +LL | if let Some(true) = k {} + | ^^^^^^^^^^^^^^^^^^ help: try: `k == Some(&true)` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:92:8 + | +LL | if let Some(&false) = k {} + | ^^^^^^^^^^^^^^^^^^^^ help: try: `k == Some(&false)` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:93:8 + | +LL | if let Some(true) = &k {} + | ^^^^^^^^^^^^^^^^^^^ help: try: `&k == &Some(&true)` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:94:8 + | +LL | if let Some(false) = &&k {} + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `&&k == &&Some(&false)` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:95:8 + | +LL | if let None = k {} + | ^^^^^^^^^^^^ help: try: `k == None` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:96:8 + | +LL | if let Generic2 { + | ________^ +LL | | a: Generic2 { a: "yyy", b: 3 }, +LL | | b: Generic2 { +LL | | a: Enum::UnitVariant, +LL | | b: false, +LL | | }, +LL | | } = l + | |_________^ help: try: `l == (Generic2 { a: Generic2 { a: "yyy", b: 3 }, b: Generic2 { a: &Enum::UnitVariant, b: false } })` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:104:8 + | +LL | if let Generic2 { a: 3, b: 5 } = m {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `m == (Generic2 { a: 3, b: 5 })` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:105:8 + | +LL | if let Some("yyy") = n {} + | ^^^^^^^^^^^^^^^^^^^ help: try: `n == Some("yyy")` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:107:13 + | +LL | let _ = matches!(c, Some(2)); + | ^^^^^^^^^^^^^^^^^^^^ help: try: `c == Some(2)` + | + = note: `-D clippy::equatable-matches` implied by `-D warnings` + +error: this pattern matching can be expressed using equality + --> $DIR/all.rs:109:11 + | +LL | while let Some(2) = o.next() {} + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `o.next() == Some(&2)` + +error: aborting due to 23 previous errors + diff --git a/tests/ui-toml/equatable_pattern/clippy.toml b/tests/ui-toml/equatable_pattern/clippy.toml new file mode 100644 index 000000000000..5d792c8393a0 --- /dev/null +++ b/tests/ui-toml/equatable_pattern/clippy.toml @@ -0,0 +1 @@ +equatable-pattern = "All" diff --git a/tests/ui/equatable_if_let.fixed b/tests/ui/equatable_if_let.fixed index 053667e82133..417c250a2fa7 100644 --- a/tests/ui/equatable_if_let.fixed +++ b/tests/ui/equatable_if_let.fixed @@ -76,52 +76,30 @@ fn main() { // true if a == 2 {} + if "world" == "hello" {} if a.cmp(&b) == Ordering::Greater {} - if c == Some(2) {} - if d == (Struct { a: 2, b: false }) {} - if e == Enum::TupleVariant(32, 64) {} - if e == (Enum::RecordVariant { a: 64, b: 32 }) {} if e == Enum::UnitVariant {} - if (e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false }) {} if Some(g) == None {} - if i == Generic::VA(Enum::UnitVariant) {} if i == Generic::VC {} - if j[1..3] == [7, 5] {} - if j[..] == [1, 2, 3, 4] {} - if k == Some(&true) {} - if k == Some(&false) {} - if &k == &Some(&true) {} - if &&k == &&Some(&false) {} if k == None {} - if l == (Generic2 { a: Generic2 { a: "yyy", b: 3 }, b: Generic2 { a: &Enum::UnitVariant, b: false } }) - {} - if m == (Generic2 { a: 3, b: 5 }) {} - if n == Some("yyy") {} - let _ = c == Some(2); - - while o.next() == Some(&2) {} + let _ = b == 2; // false + if let Some(2) = c {} + if let Struct { a: 2, b: false } = d {} + if let Enum::TupleVariant(32, 64) = e {} + if let Enum::RecordVariant { a: 64, b: 32 } = e {} + if let Some("yyy") = n {} if let 2 | 3 = a {} if let x @ 2 = a {} - if let Some(3 | 4) = c {} - if let Struct { a, b: false } = d {} - if let Struct { a: 2, b: x } = d {} - if let NotPartialEq::A = f {} - if let NotStructuralEq::A = g {} - if let Some(NotPartialEq::A) = Some(f) {} if let None = Some(f) {} - if let Some(NotStructuralEq::A) = Some(g) {} - if let Generic::VA(Enum::UnitVariant) = h {} - if let Generic::VB(NotPartialEq::A) = h {} - if let Generic::VC = h {} - if let Generic::VB(NotStructuralEq::A) = i {} if let [7, _] = j[2..] {} if let [1, 2 | 5, 3, 4] = j[..] {} if let [2, ..] = j[..] {} + let _ = matches!(c, Some(2)); let _ = matches!(c, Some(x)); let _ = matches!(c, Some(x) if x == 2); let _ = matches!(c, Some(2) if 3 > 5); diff --git a/tests/ui/equatable_if_let.rs b/tests/ui/equatable_if_let.rs index 7c2d8cf9d919..cdac89b8f1de 100644 --- a/tests/ui/equatable_if_let.rs +++ b/tests/ui/equatable_if_let.rs @@ -76,58 +76,30 @@ fn main() { // true if let 2 = a {} + if let "hello" = "world" {} if let Ordering::Greater = a.cmp(&b) {} - if let Some(2) = c {} - if let Struct { a: 2, b: false } = d {} - if let Enum::TupleVariant(32, 64) = e {} - if let Enum::RecordVariant { a: 64, b: 32 } = e {} if let Enum::UnitVariant = e {} - if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {} if let None = Some(g) {} - if let Generic::VA(Enum::UnitVariant) = i {} if let Generic::VC = i {} - if let [7, 5] = j[1..3] {} - if let [1, 2, 3, 4] = j[..] {} - if let Some(true) = k {} - if let Some(&false) = k {} - if let Some(true) = &k {} - if let Some(false) = &&k {} if let None = k {} - if let Generic2 { - a: Generic2 { a: "yyy", b: 3 }, - b: Generic2 { - a: Enum::UnitVariant, - b: false, - }, - } = l - {} - if let Generic2 { a: 3, b: 5 } = m {} - if let Some("yyy") = n {} - let _ = matches!(c, Some(2)); - - while let Some(2) = o.next() {} + let _ = matches!(b, 2); // false + if let Some(2) = c {} + if let Struct { a: 2, b: false } = d {} + if let Enum::TupleVariant(32, 64) = e {} + if let Enum::RecordVariant { a: 64, b: 32 } = e {} + if let Some("yyy") = n {} if let 2 | 3 = a {} if let x @ 2 = a {} - if let Some(3 | 4) = c {} - if let Struct { a, b: false } = d {} - if let Struct { a: 2, b: x } = d {} - if let NotPartialEq::A = f {} - if let NotStructuralEq::A = g {} - if let Some(NotPartialEq::A) = Some(f) {} if let None = Some(f) {} - if let Some(NotStructuralEq::A) = Some(g) {} - if let Generic::VA(Enum::UnitVariant) = h {} - if let Generic::VB(NotPartialEq::A) = h {} - if let Generic::VC = h {} - if let Generic::VB(NotStructuralEq::A) = i {} if let [7, _] = j[2..] {} if let [1, 2 | 5, 3, 4] = j[..] {} if let [2, ..] = j[..] {} + let _ = matches!(c, Some(2)); let _ = matches!(c, Some(x)); let _ = matches!(c, Some(x) if x == 2); let _ = matches!(c, Some(2) if 3 > 5); diff --git a/tests/ui/equatable_if_let.stderr b/tests/ui/equatable_if_let.stderr index 993974906df7..86b297e06b30 100644 --- a/tests/ui/equatable_if_let.stderr +++ b/tests/ui/equatable_if_let.stderr @@ -9,143 +9,46 @@ LL | if let 2 = a {} error: this pattern matching can be expressed using equality --> $DIR/equatable_if_let.rs:79:8 | -LL | if let Ordering::Greater = a.cmp(&b) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater` +LL | if let "hello" = "world" {} + | ^^^^^^^^^^^^^^^^^^^^^ help: try: `"world" == "hello"` error: this pattern matching can be expressed using equality --> $DIR/equatable_if_let.rs:80:8 | -LL | if let Some(2) = c {} - | ^^^^^^^^^^^^^^^ help: try: `c == Some(2)` +LL | if let Ordering::Greater = a.cmp(&b) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater` error: this pattern matching can be expressed using equality --> $DIR/equatable_if_let.rs:81: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 - --> $DIR/equatable_if_let.rs:82: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 - --> $DIR/equatable_if_let.rs:83: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 - --> $DIR/equatable_if_let.rs:84:8 - | LL | if let Enum::UnitVariant = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:85: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 equality - --> $DIR/equatable_if_let.rs:86:8 + --> $DIR/equatable_if_let.rs:82:8 | LL | if let None = Some(g) {} | ^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == None` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:87:8 - | -LL | if let Generic::VA(Enum::UnitVariant) = i {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i == Generic::VA(Enum::UnitVariant)` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:88:8 + --> $DIR/equatable_if_let.rs:83:8 | LL | if let Generic::VC = i {} | ^^^^^^^^^^^^^^^^^^^ help: try: `i == Generic::VC` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:89:8 - | -LL | if let [7, 5] = j[1..3] {} - | ^^^^^^^^^^^^^^^^^^^^ help: try: `j[1..3] == [7, 5]` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:90:8 - | -LL | if let [1, 2, 3, 4] = j[..] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `j[..] == [1, 2, 3, 4]` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:91:8 - | -LL | if let Some(true) = k {} - | ^^^^^^^^^^^^^^^^^^ help: try: `k == Some(&true)` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:92:8 - | -LL | if let Some(&false) = k {} - | ^^^^^^^^^^^^^^^^^^^^ help: try: `k == Some(&false)` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:93:8 - | -LL | if let Some(true) = &k {} - | ^^^^^^^^^^^^^^^^^^^ help: try: `&k == &Some(&true)` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:94:8 - | -LL | if let Some(false) = &&k {} - | ^^^^^^^^^^^^^^^^^^^^^ help: try: `&&k == &&Some(&false)` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:95:8 + --> $DIR/equatable_if_let.rs:84:8 | LL | if let None = k {} | ^^^^^^^^^^^^ help: try: `k == None` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:96:8 + --> $DIR/equatable_if_let.rs:86:13 | -LL | if let Generic2 { - | ________^ -LL | | a: Generic2 { a: "yyy", b: 3 }, -LL | | b: Generic2 { -LL | | a: Enum::UnitVariant, -LL | | b: false, -LL | | }, -LL | | } = l - | |_________^ help: try: `l == (Generic2 { a: Generic2 { a: "yyy", b: 3 }, b: Generic2 { a: &Enum::UnitVariant, b: false } })` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:104:8 - | -LL | if let Generic2 { a: 3, b: 5 } = m {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `m == (Generic2 { a: 3, b: 5 })` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:105:8 - | -LL | if let Some("yyy") = n {} - | ^^^^^^^^^^^^^^^^^^^ help: try: `n == Some("yyy")` - -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:107:13 - | -LL | let _ = matches!(c, Some(2)); - | ^^^^^^^^^^^^^^^^^^^^ help: try: `c == Some(2)` +LL | let _ = matches!(b, 2); + | ^^^^^^^^^^^^^^ help: try: `b == 2` | = note: `-D clippy::equatable-matches` implied by `-D warnings` -error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:109:11 - | -LL | while let Some(2) = o.next() {} - | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `o.next() == Some(&2)` - -error: aborting due to 23 previous errors +error: aborting due to 8 previous errors