From edfd2b99097c6e0eb44790ff7c28b8cadf39cfeb Mon Sep 17 00:00:00 2001
From: hkalbasi <hamidrezakalbasi@protonmail.com>
Date: Wed, 6 Oct 2021 16:35:31 +0330
Subject: [PATCH] upgrade equatable_if_let to style

---
 CHANGELOG.md                                  |   1 +
 clippy_lints/src/casts/cast_lossless.rs       |   6 +-
 .../src/casts/cast_possible_truncation.rs     |   4 +-
 clippy_lints/src/equatable_if_let.rs          | 229 ++++++++++++++----
 clippy_lints/src/lib.register_all.rs          |   1 +
 clippy_lints/src/lib.register_lints.rs        |   1 +
 clippy_lints/src/lib.register_nursery.rs      |   1 -
 clippy_lints/src/lib.register_pedantic.rs     |   1 +
 clippy_lints/src/lib.register_style.rs        |   1 +
 clippy_lints/src/manual_async_fn.rs           |   2 +-
 clippy_lints/src/manual_map.rs                |   2 +-
 clippy_lints/src/map_clone.rs                 |   2 +-
 .../src/methods/inefficient_to_string.rs      |   2 +-
 clippy_lints/src/methods/mod.rs               |   2 +-
 clippy_lints/src/methods/or_fun_call.rs       |   4 +-
 clippy_lints/src/multiple_crate_versions.rs   |  10 +-
 clippy_lints/src/needless_borrow.rs           |   2 +-
 clippy_lints/src/redundant_clone.rs           |   4 +-
 clippy_lints/src/same_name_method.rs          |   4 +-
 .../src/transmute/transmute_ref_to_ref.rs     |   2 +-
 clippy_lints/src/unused_async.rs              |   2 +-
 clippy_lints/src/utils/internal_lints.rs      |   2 +-
 clippy_lints/src/write.rs                     |   6 +-
 clippy_utils/src/ast_utils.rs                 |  12 +-
 clippy_utils/src/higher.rs                    |  36 +++
 tests/lint_message_convention.rs              |   2 +-
 tests/ui-internal/if_chain_style.rs           |   2 +-
 tests/ui/equatable_if_let.fixed               |  69 +++++-
 tests/ui/equatable_if_let.rs                  |  71 +++++-
 tests/ui/equatable_if_let.stderr              | 117 +++++++--
 30 files changed, 487 insertions(+), 113 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7fdb300c9774..b0b21343dc75 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2696,6 +2696,7 @@ Released 2018-09-13
 [`enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names
 [`eq_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#eq_op
 [`equatable_if_let`]: https://rust-lang.github.io/rust-clippy/master/index.html#equatable_if_let
+[`equatable_matches`]: https://rust-lang.github.io/rust-clippy/master/index.html#equatable_matches
 [`erasing_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#erasing_op
 [`eval_order_dependence`]: https://rust-lang.github.io/rust-clippy/master/index.html#eval_order_dependence
 [`excessive_precision`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision
diff --git a/clippy_lints/src/casts/cast_lossless.rs b/clippy_lints/src/casts/cast_lossless.rs
index 869deecfbd53..7b3322741fa7 100644
--- a/clippy_lints/src/casts/cast_lossless.rs
+++ b/clippy_lints/src/casts/cast_lossless.rs
@@ -65,7 +65,7 @@ fn should_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to
 
         (true, false) => {
             let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx);
-            let to_nbits = if let ty::Float(FloatTy::F32) = cast_to.kind() {
+            let to_nbits = if cast_to.kind() == &ty::Float(FloatTy::F32) {
                 32
             } else {
                 64
@@ -73,9 +73,7 @@ fn should_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to
             from_nbits < to_nbits
         },
 
-        (_, _) => {
-            matches!(cast_from.kind(), ty::Float(FloatTy::F32)) && matches!(cast_to.kind(), ty::Float(FloatTy::F64))
-        },
+        (_, _) => cast_from.kind() == &ty::Float(FloatTy::F32) && cast_to.kind() == &ty::Float(FloatTy::F64),
     }
 }
 
diff --git a/clippy_lints/src/casts/cast_possible_truncation.rs b/clippy_lints/src/casts/cast_possible_truncation.rs
index 833ad122e0d4..b24f206ab0c8 100644
--- a/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -40,9 +40,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, ca
         },
 
         (_, _) => {
-            if matches!(cast_from.kind(), &ty::Float(FloatTy::F64))
-                && matches!(cast_to.kind(), &ty::Float(FloatTy::F32))
-            {
+            if cast_from.kind() == &ty::Float(FloatTy::F64) && cast_to.kind() == &ty::Float(FloatTy::F32) {
                 "casting `f64` to `f32` may truncate the value".to_string()
             } else {
                 return;
diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs
index 0c6ba91c9430..0cbaee9cc83e 100644
--- a/clippy_lints/src/equatable_if_let.rs
+++ b/clippy_lints/src/equatable_if_let.rs
@@ -1,16 +1,21 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::implements_trait;
+use clippy_utils::{diagnostics::span_lint_and_sugg, higher::MatchesExpn};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, Pat, PatKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::Ty;
+use rustc_hir::{
+    def::{DefKind, Res},
+    Arm, Expr, ExprKind, Pat, PatKind, QPath,
+};
+use rustc_lint::{LateContext, LateLintPass, Lint};
+use rustc_middle::ty::{Adt, Ty};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::Span;
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for pattern matchings that can be expressed using equality.
+    /// Checks for `if let <pat> = <expr>` (and `while let` and similars) that can be expressed
+    /// using `if <expr> == <pat>`.
     ///
     /// ### Why is this bad?
     ///
@@ -33,68 +38,192 @@ declare_clippy_lint! {
     /// }
     /// ```
     pub EQUATABLE_IF_LET,
-    nursery,
-    "using pattern matching instead of equality"
+    style,
+    "using if let instead of if with a equality condition"
 }
 
-declare_lint_pass!(PatternEquality => [EQUATABLE_IF_LET]);
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `matches!(<expr>, <pat>)` that can be expressed
+    /// using `<expr> == <pat>`.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// It is less concise and less clear.
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// let condition = matches!(x, Some(2));
+    /// ```
+    /// Should be written
+    /// ```rust,ignore
+    /// let condition = x == Some(2);
+    /// ```
+    pub EQUATABLE_MATCHES,
+    pedantic,
+    "using `matches!` instead of equality"
+}
+
+declare_lint_pass!(PatternEquality => [EQUATABLE_IF_LET, EQUATABLE_MATCHES]);
 
-/// detects if pattern matches just one thing
-fn unary_pattern(pat: &Pat<'_>) -> bool {
-    fn array_rec(pats: &[Pat<'_>]) -> bool {
-        pats.iter().all(unary_pattern)
+fn equatable_pattern(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
+    fn array_rec(cx: &LateContext<'_>, pats: &[Pat<'_>]) -> bool {
+        pats.iter().all(|x| equatable_pattern(cx, x))
     }
-    match &pat.kind {
-        PatKind::Slice(_, _, _) | PatKind::Range(_, _, _) | PatKind::Binding(..) | PatKind::Wild | PatKind::Or(_) => {
+    fn is_derived(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
+        let ty = cx.typeck_results().pat_ty(pat);
+        if let Some(def_id) = cx.tcx.lang_items().structural_peq_trait() {
+            implements_trait(cx, ty, def_id, &[ty.into()])
+        } else {
             false
+        }
+    }
+    match &pat.kind {
+        PatKind::Slice(a, None, []) => array_rec(cx, a),
+        PatKind::Struct(_, a, etc) => !etc && is_derived(cx, pat) && a.iter().all(|x| equatable_pattern(cx, x.pat)),
+        PatKind::Tuple(a, etc) => !etc.is_some() && array_rec(cx, a),
+        PatKind::TupleStruct(_, a, etc) => !etc.is_some() && is_derived(cx, pat) && array_rec(cx, a),
+        PatKind::Ref(x, _) | PatKind::Box(x) => equatable_pattern(cx, x),
+        PatKind::Path(QPath::Resolved(_, b)) => match b.res {
+            Res::Def(DefKind::Const, _) => true,
+            _ => is_derived(cx, pat),
         },
-        PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
-        PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => !etc.is_some() && array_rec(a),
-        PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x),
-        PatKind::Path(_) | PatKind::Lit(_) => true,
+        PatKind::Path(_) => is_derived(cx, pat),
+        PatKind::Lit(_) => true,
+        PatKind::Slice(..) | PatKind::Range(..) | PatKind::Binding(..) | PatKind::Wild | PatKind::Or(_) => false,
     }
 }
 
-fn is_structural_partial_eq(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: Ty<'tcx>) -> bool {
+fn is_partial_eq(cx: &LateContext<'tcx>, t1: Ty<'tcx>, t2: Ty<'tcx>) -> bool {
     if let Some(def_id) = cx.tcx.lang_items().eq_trait() {
-        implements_trait(cx, ty, def_id, &[other.into()])
+        implements_trait(cx, t1, def_id, &[t2.into()])
     } else {
         false
     }
 }
 
+fn pat_to_string(cx: &LateContext<'tcx>, app: &mut Applicability, pat: &Pat<'_>, goal: Ty<'_>) -> Option<String> {
+    fn inner(cx: &LateContext<'tcx>, app: &mut Applicability, pat: &Pat<'_>, goal: Ty<'_>, r: &mut String) -> bool {
+        let ty = cx.typeck_results().pat_ty(pat);
+        if ty == goal {
+            match &pat.kind {
+                PatKind::TupleStruct(q, ..) | PatKind::Struct(q, ..) => {
+                    let (adt_def, generic_args) = if let Adt(x, y) = ty.kind() {
+                        (x, y)
+                    } else {
+                        return false; // shouldn't happen
+                    };
+                    let path = if let QPath::Resolved(.., p) = q {
+                        p
+                    } else {
+                        return false; // give up
+                    };
+                    let var = adt_def.variant_of_res(path.res);
+                    match &pat.kind {
+                        PatKind::TupleStruct(_, params, _) => {
+                            *r += &*snippet_with_applicability(cx, path.span, "..", app);
+                            *r += "(";
+                            for (i, (p, f)) in params.iter().zip(var.fields.iter()).enumerate() {
+                                if i != 0 {
+                                    *r += ", ";
+                                }
+                                inner(cx, app, p, f.ty(cx.tcx, generic_args), r);
+                            }
+                            *r += ")";
+                        },
+                        PatKind::Struct(_, fields, _) => {
+                            *r += &*snippet_with_applicability(cx, path.span, "..", app);
+                            *r += " { ";
+                            for (i, p) in fields.iter().enumerate() {
+                                if i != 0 {
+                                    *r += ", ";
+                                }
+                                *r += &*snippet_with_applicability(cx, p.ident.span, "..", app);
+                                *r += ": ";
+                                if let Some(x) = var.fields.iter().find(|f| f.ident == p.ident) {
+                                    inner(cx, app, p.pat, x.ty(cx.tcx, generic_args), r);
+                                } else {
+                                    return false; // won't happen
+                                }
+                            }
+                            *r += " }";
+                        },
+                        _ => return false, // won't happen
+                    }
+                },
+                _ => {
+                    *r += &*snippet_with_applicability(cx, pat.span, "..", app);
+                },
+            }
+            return true;
+        }
+        if goal.is_ref() {
+            if let Some(tam) = goal.builtin_deref(true) {
+                *r += "&";
+                return inner(cx, app, pat, tam.ty, r);
+            }
+        }
+        false
+    }
+    let mut r = "".to_string();
+    if let PatKind::Struct(..) = pat.kind {
+        r += "(";
+    }
+    let success = inner(cx, app, pat, goal, &mut r);
+    if let PatKind::Struct(..) = pat.kind {
+        r += ")";
+    }
+    if !success {
+        return None;
+    }
+    Some(r)
+}
+
+fn emit_lint(cx: &LateContext<'tcx>, pat: &Pat<'_>, exp: &Expr<'_>, span: Span, lint: &'static Lint) {
+    if_chain! {
+        if equatable_pattern(cx, 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,
+                lint,
+                span,
+                "this pattern matching can be expressed using equality",
+                "try",
+                format!(
+                    "{} == {}",
+                    exp_str,
+                    pat_str,
+                ),
+                app,
+            );
+        }
+    }
+}
+
 impl<'tcx> LateLintPass<'tcx> for PatternEquality {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        if_chain! {
-            if let ExprKind::Let(pat, exp, _) = expr.kind;
-            if unary_pattern(pat);
-            let exp_ty = cx.typeck_results().expr_ty(exp);
-            let pat_ty = cx.typeck_results().pat_ty(pat);
-            if is_structural_partial_eq(cx, exp_ty, pat_ty);
-            then {
-
-                let mut applicability = Applicability::MachineApplicable;
-                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(),
-                };
-                span_lint_and_sugg(
-                    cx,
-                    EQUATABLE_IF_LET,
-                    expr.span,
-                    "this pattern matching can be expressed using equality",
-                    "try",
-                    format!(
-                        "{} == {}",
-                        snippet_with_applicability(cx, exp.span, "..", &mut applicability),
-                        pat_str,
-                    ),
-                    applicability,
-                );
-            }
+        if let ExprKind::Let(pat, exp, _) = expr.kind {
+            emit_lint(cx, pat, exp, expr.span, EQUATABLE_IF_LET);
+        }
+        if let Some(MatchesExpn {
+            call_site,
+            arm: Arm { pat, guard: None, .. },
+            exp,
+        }) = MatchesExpn::parse(expr)
+        {
+            emit_lint(cx, pat, exp, call_site, EQUATABLE_MATCHES);
         }
     }
 }
diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs
index 3e6e0244754f..e0b58469b6b6 100644
--- a/clippy_lints/src/lib.register_all.rs
+++ b/clippy_lints/src/lib.register_all.rs
@@ -51,6 +51,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(enum_variants::MODULE_INCEPTION),
     LintId::of(eq_op::EQ_OP),
     LintId::of(eq_op::OP_REF),
+    LintId::of(equatable_if_let::EQUATABLE_IF_LET),
     LintId::of(erasing_op::ERASING_OP),
     LintId::of(escape::BOXED_LOCAL),
     LintId::of(eta_reduction::REDUNDANT_CLOSURE),
diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs
index 2ba2b3da55cd..e7e12fc9d7cc 100644
--- a/clippy_lints/src/lib.register_lints.rs
+++ b/clippy_lints/src/lib.register_lints.rs
@@ -117,6 +117,7 @@ store.register_lints(&[
     eq_op::EQ_OP,
     eq_op::OP_REF,
     equatable_if_let::EQUATABLE_IF_LET,
+    equatable_if_let::EQUATABLE_MATCHES,
     erasing_op::ERASING_OP,
     escape::BOXED_LOCAL,
     eta_reduction::REDUNDANT_CLOSURE,
diff --git a/clippy_lints/src/lib.register_nursery.rs b/clippy_lints/src/lib.register_nursery.rs
index 96e0b421094d..32606e570d8c 100644
--- a/clippy_lints/src/lib.register_nursery.rs
+++ b/clippy_lints/src/lib.register_nursery.rs
@@ -8,7 +8,6 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
     LintId::of(copies::BRANCHES_SHARING_CODE),
     LintId::of(disallowed_method::DISALLOWED_METHOD),
     LintId::of(disallowed_type::DISALLOWED_TYPE),
-    LintId::of(equatable_if_let::EQUATABLE_IF_LET),
     LintId::of(fallible_impl_from::FALLIBLE_IMPL_FROM),
     LintId::of(floating_point_arithmetic::IMPRECISE_FLOPS),
     LintId::of(floating_point_arithmetic::SUBOPTIMAL_FLOPS),
diff --git a/clippy_lints/src/lib.register_pedantic.rs b/clippy_lints/src/lib.register_pedantic.rs
index 6533b94e82bd..7274efcd492e 100644
--- a/clippy_lints/src/lib.register_pedantic.rs
+++ b/clippy_lints/src/lib.register_pedantic.rs
@@ -28,6 +28,7 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
     LintId::of(doc::MISSING_PANICS_DOC),
     LintId::of(empty_enum::EMPTY_ENUM),
     LintId::of(enum_variants::MODULE_NAME_REPETITIONS),
+    LintId::of(equatable_if_let::EQUATABLE_MATCHES),
     LintId::of(eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS),
     LintId::of(excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS),
     LintId::of(excessive_bools::STRUCT_EXCESSIVE_BOOLS),
diff --git a/clippy_lints/src/lib.register_style.rs b/clippy_lints/src/lib.register_style.rs
index a39c111c5742..3ae1fb829593 100644
--- a/clippy_lints/src/lib.register_style.rs
+++ b/clippy_lints/src/lib.register_style.rs
@@ -20,6 +20,7 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
     LintId::of(enum_variants::ENUM_VARIANT_NAMES),
     LintId::of(enum_variants::MODULE_INCEPTION),
     LintId::of(eq_op::OP_REF),
+    LintId::of(equatable_if_let::EQUATABLE_IF_LET),
     LintId::of(eta_reduction::REDUNDANT_CLOSURE),
     LintId::of(float_literal::EXCESSIVE_PRECISION),
     LintId::of(from_over_into::FROM_OVER_INTO),
diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs
index b632af455f85..14b6c36627e7 100644
--- a/clippy_lints/src/manual_async_fn.rs
+++ b/clippy_lints/src/manual_async_fn.rs
@@ -165,7 +165,7 @@ fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName])
     // - There's only one output lifetime bound using `+ '_`
     // - All input lifetimes are explicitly bound to the output
     input_lifetimes.is_empty()
-        || (output_lifetimes.len() == 1 && matches!(output_lifetimes[0], LifetimeName::Underscore))
+        || (output_lifetimes.len() == 1 && output_lifetimes[0] == LifetimeName::Underscore)
         || input_lifetimes
             .iter()
             .all(|in_lt| output_lifetimes.iter().any(|out_lt| in_lt == out_lt))
diff --git a/clippy_lints/src/manual_map.rs b/clippy_lints/src/manual_map.rs
index b5f573cb104e..2c26ab02a4fe 100644
--- a/clippy_lints/src/manual_map.rs
+++ b/clippy_lints/src/manual_map.rs
@@ -170,7 +170,7 @@ impl LateLintPass<'_> for ManualMap {
                     }
 
                     // `ref` and `ref mut` annotations were handled earlier.
-                    let annotation = if matches!(annotation, BindingAnnotation::Mutable) {
+                    let annotation = if annotation == BindingAnnotation::Mutable {
                         "mut "
                     } else {
                         ""
diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs
index 394606200bb0..f246817ab414 100644
--- a/clippy_lints/src/map_clone.rs
+++ b/clippy_lints/src/map_clone.rs
@@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for MapClone {
                                 then {
                                     let obj_ty = cx.typeck_results().expr_ty(obj);
                                     if let ty::Ref(_, ty, mutability) = obj_ty.kind() {
-                                        if matches!(mutability, Mutability::Not) {
+                                        if mutability == &Mutability::Not {
                                             let copy = is_copy(cx, ty);
                                             lint(cx, e.span, args[0].span, copy);
                                         }
diff --git a/clippy_lints/src/methods/inefficient_to_string.rs b/clippy_lints/src/methods/inefficient_to_string.rs
index 950ec62c9fe4..10e377cddee6 100644
--- a/clippy_lints/src/methods/inefficient_to_string.rs
+++ b/clippy_lints/src/methods/inefficient_to_string.rs
@@ -51,7 +51,7 @@ pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
 /// Returns whether `ty` specializes `ToString`.
 /// Currently, these are `str`, `String`, and `Cow<'_, str>`.
 fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
-    if let ty::Str = ty.kind() {
+    if ty.kind() == &ty::Str {
         return true;
     }
 
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index b26d11c0d6b0..d980777bd44c 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -2456,7 +2456,7 @@ impl OutType {
 
 fn is_bool(ty: &hir::Ty<'_>) -> bool {
     if let hir::TyKind::Path(QPath::Resolved(_, path)) = ty.kind {
-        matches!(path.res, Res::PrimTy(PrimTy::Bool))
+        path.res == Res::PrimTy(PrimTy::Bool)
     } else {
         false
     }
diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs
index a4d3f0bfb6c1..8b0220664ef1 100644
--- a/clippy_lints/src/methods/or_fun_call.rs
+++ b/clippy_lints/src/methods/or_fun_call.rs
@@ -51,8 +51,8 @@ pub(super) fn check<'tcx>(
             let path = last_path_segment(qpath).ident.name;
             // needs to target Default::default in particular or be *::new and have a Default impl
             // available
-            if (matches!(path, kw::Default) && is_default_default())
-                || (matches!(path, sym::new) && implements_default(arg, default_trait_id));
+            if (path == kw::Default && is_default_default())
+                || (path == sym::new && implements_default(arg, default_trait_id));
 
             then {
                 let mut applicability = Applicability::MachineApplicable;
diff --git a/clippy_lints/src/multiple_crate_versions.rs b/clippy_lints/src/multiple_crate_versions.rs
index 1c61970fdc8b..bb94a3096fc5 100644
--- a/clippy_lints/src/multiple_crate_versions.rs
+++ b/clippy_lints/src/multiple_crate_versions.rs
@@ -84,13 +84,9 @@ impl LateLintPass<'_> for MultipleCrateVersions {
 
 fn is_normal_dep(nodes: &[Node], local_id: &PackageId, dep_id: &PackageId) -> bool {
     fn depends_on(node: &Node, dep_id: &PackageId) -> bool {
-        node.deps.iter().any(|dep| {
-            dep.pkg == *dep_id
-                && dep
-                    .dep_kinds
-                    .iter()
-                    .any(|info| matches!(info.kind, DependencyKind::Normal))
-        })
+        node.deps
+            .iter()
+            .any(|dep| dep.pkg == *dep_id && dep.dep_kinds.iter().any(|info| info.kind == DependencyKind::Normal))
     }
 
     nodes
diff --git a/clippy_lints/src/needless_borrow.rs b/clippy_lints/src/needless_borrow.rs
index 1b2495d764d2..d10deeb568e0 100644
--- a/clippy_lints/src/needless_borrow.rs
+++ b/clippy_lints/src/needless_borrow.rs
@@ -116,7 +116,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow {
                         ..
                     }] = *adj3
                     {
-                        let help_msg_ty = if matches!(mutability, Mutability::Not) {
+                        let help_msg_ty = if mutability == Mutability::Not {
                             format!("&{}", ty)
                         } else {
                             format!("&mut {}", ty)
diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs
index 7041e4f980ef..bc9d1c911bbd 100644
--- a/clippy_lints/src/redundant_clone.rs
+++ b/clippy_lints/src/redundant_clone.rs
@@ -323,7 +323,7 @@ fn find_stmt_assigns_to<'tcx>(
             Some(base_local_and_movability(cx, mir, *place))
         },
         (false, mir::Rvalue::Ref(_, _, place)) => {
-            if let [mir::ProjectionElem::Deref] = place.as_ref().projection {
+            if place.as_ref().projection == [mir::ProjectionElem::Deref] {
                 Some(base_local_and_movability(cx, mir, *place))
             } else {
                 None
@@ -355,7 +355,7 @@ fn base_local_and_movability<'tcx>(
     let PlaceRef { local, mut projection } = place.as_ref();
     while let [base @ .., elem] = projection {
         projection = base;
-        deref |= matches!(elem, mir::ProjectionElem::Deref);
+        deref |= elem == &mir::ProjectionElem::Deref;
         field |= matches!(elem, mir::ProjectionElem::Field(..))
             && has_drop(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
         slice |= matches!(elem, mir::ProjectionElem::Index(..))
diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs
index 014898e6dab1..2cd2999474d2 100644
--- a/clippy_lints/src/same_name_method.rs
+++ b/clippy_lints/src/same_name_method.rs
@@ -83,9 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
                                     cx.tcx
                                         .associated_items(did)
                                         .in_definition_order()
-                                        .filter(|assoc_item| {
-                                            matches!(assoc_item.kind, AssocKind::Fn)
-                                        })
+                                        .filter(|assoc_item| assoc_item.kind == AssocKind::Fn)
                                         .map(|assoc_item| assoc_item.ident.name)
                                         .collect()
                                 }else{
diff --git a/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/clippy_lints/src/transmute/transmute_ref_to_ref.rs
index d105e37abf9c..50eca0a9cc21 100644
--- a/clippy_lints/src/transmute/transmute_ref_to_ref.rs
+++ b/clippy_lints/src/transmute/transmute_ref_to_ref.rs
@@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(
     if let (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) = (&from_ty.kind(), &to_ty.kind()) {
         if_chain! {
             if let (&ty::Slice(slice_ty), &ty::Str) = (&ty_from.kind(), &ty_to.kind());
-            if let ty::Uint(ty::UintTy::U8) = slice_ty.kind();
+            if slice_ty.kind() == &ty::Uint(ty::UintTy::U8);
             if from_mutbl == to_mutbl;
             then {
                 let postfix = if *from_mutbl == Mutability::Mut {
diff --git a/clippy_lints/src/unused_async.rs b/clippy_lints/src/unused_async.rs
index f4808682b692..fe16217b8099 100644
--- a/clippy_lints/src/unused_async.rs
+++ b/clippy_lints/src/unused_async.rs
@@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
         hir_id: HirId,
     ) {
         if let FnKind::ItemFn(_, _, FnHeader { asyncness, .. }, _) = &fn_kind {
-            if matches!(asyncness, IsAsync::Async) {
+            if asyncness == &IsAsync::Async {
                 let mut visitor = AsyncFnVisitor { cx, found_await: false };
                 walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), span, hir_id);
                 if !visitor.found_await {
diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs
index 3e2a4e9748db..aa42630b0a6b 100644
--- a/clippy_lints/src/utils/internal_lints.rs
+++ b/clippy_lints/src/utils/internal_lints.rs
@@ -536,7 +536,7 @@ impl<'tcx> LateLintPass<'tcx> for OuterExpnDataPass {
         let method_names: Vec<SymbolStr> = method_names.iter().map(|s| s.as_str()).collect();
         let method_names: Vec<&str> = method_names.iter().map(|s| &**s).collect();
         if_chain! {
-            if let ["expn_data", "outer_expn"] = method_names.as_slice();
+            if method_names.as_slice() == ["expn_data", "outer_expn"];
             let args = arg_lists[1];
             if args.len() == 1;
             let self_arg = &args[0];
diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs
index 85d1f65c51f0..890ff0e6d506 100644
--- a/clippy_lints/src/write.rs
+++ b/clippy_lints/src/write.rs
@@ -564,13 +564,13 @@ impl Write {
                 LitKind::StrRaw(_) | LitKind::ByteStrRaw(_) if matches!(fmtstr.style, StrStyle::Raw(_)) => {
                     lit.token.symbol.as_str().replace("{", "{{").replace("}", "}}")
                 },
-                LitKind::Str | LitKind::ByteStr if matches!(fmtstr.style, StrStyle::Cooked) => {
+                LitKind::Str | LitKind::ByteStr if fmtstr.style == StrStyle::Cooked => {
                     lit.token.symbol.as_str().replace("{", "{{").replace("}", "}}")
                 },
                 LitKind::StrRaw(_) | LitKind::Str | LitKind::ByteStrRaw(_) | LitKind::ByteStr => continue,
                 LitKind::Byte | LitKind::Char => match &*lit.token.symbol.as_str() {
-                    "\"" if matches!(fmtstr.style, StrStyle::Cooked) => "\\\"",
-                    "\"" if matches!(fmtstr.style, StrStyle::Raw(0)) => continue,
+                    "\"" if fmtstr.style == StrStyle::Cooked => "\\\"",
+                    "\"" if fmtstr.style == StrStyle::Raw(0) => continue,
                     "\\\\" if matches!(fmtstr.style, StrStyle::Raw(_)) => "\\",
                     "\\'" => "'",
                     "{" => "{{",
diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs
index 2fa98831c774..e536f2a90a89 100644
--- a/clippy_utils/src/ast_utils.rs
+++ b/clippy_utils/src/ast_utils.rs
@@ -278,7 +278,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         },
         (Trait(box TraitKind(la, lu, lg, lb, li)), Trait(box TraitKind(ra, ru, rg, rb, ri))) => {
             la == ra
-                && matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
+                && matches!(lu, Unsafe::Yes(_)) == matches!(ru, Unsafe::Yes(_))
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
                 && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
@@ -306,10 +306,10 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 items: ri,
             }),
         ) => {
-            matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
-                && matches!(lp, ImplPolarity::Positive) == matches!(rp, ImplPolarity::Positive)
+            matches!(lu, Unsafe::Yes(_)) == matches!(ru, Unsafe::Yes(_))
+                && matches!(lp, ImplPolarity::Negative(_)) == matches!(rp, ImplPolarity::Negative(_))
                 && eq_defaultness(*ld, *rd)
-                && matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)
+                && matches!(lc, ast::Const::Yes(_)) == matches!(rc, ast::Const::Yes(_))
                 && eq_generics(lg, rg)
                 && both(lot, rot, |l, r| eq_path(&l.path, &r.path))
                 && eq_ty(lst, rst)
@@ -388,9 +388,9 @@ pub fn eq_fn_sig(l: &FnSig, r: &FnSig) -> bool {
 }
 
 pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool {
-    matches!(l.unsafety, Unsafe::No) == matches!(r.unsafety, Unsafe::No)
+    matches!(l.unsafety, Unsafe::Yes(_)) == matches!(r.unsafety, Unsafe::Yes(_))
         && l.asyncness.is_async() == r.asyncness.is_async()
-        && matches!(l.constness, Const::No) == matches!(r.constness, Const::No)
+        && matches!(l.constness, Const::Yes(_)) == matches!(r.constness, Const::Yes(_))
         && eq_ext(&l.ext, &r.ext)
 }
 
diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs
index ba4d50bf7446..e3d88b1f2d4e 100644
--- a/clippy_utils/src/higher.rs
+++ b/clippy_utils/src/higher.rs
@@ -467,6 +467,42 @@ pub fn extract_assert_macro_args<'tcx>(e: &'tcx Expr<'tcx>) -> Option<Vec<&'tcx
     None
 }
 
+/// A parsed `matches!` expansion
+#[derive(Debug)]
+pub struct MatchesExpn<'tcx> {
+    /// Span of `matches!(..)`
+    pub call_site: Span,
+    /// Second parameter of `matches!`
+    pub arm: &'tcx Arm<'tcx>,
+    /// First parameter of `matches!`
+    pub exp: &'tcx Expr<'tcx>,
+}
+
+impl MatchesExpn<'tcx> {
+    /// Parses an expanded `matches!` invocation
+    pub fn parse(expr: &'tcx Expr<'tcx>) -> Option<Self> {
+        if_chain! {
+            if let ExprKind::Match(exp, [arm_true, arm_false], _) = expr.kind;
+            if let ExprKind::Lit(lit_true) = &arm_true.body.kind;
+            if lit_true.node == LitKind::Bool(true);
+            if let ExprKind::Lit(lit_false) = &arm_false.body.kind;
+            if lit_false.node == LitKind::Bool(false);
+            // there is no sym::matches ?!
+            //if let ExpnKind::Macro(_, sym::matches) = expn_data.kind;
+            then {
+                let expn_data = expr.span.ctxt().outer_expn_data();
+                Some(MatchesExpn {
+                    call_site: expn_data.call_site,
+                    arm: arm_true,
+                    exp,
+                })
+            } else {
+                None
+            }
+        }
+    }
+}
+
 /// A parsed `format!` expansion
 pub struct FormatExpn<'tcx> {
     /// Span of `format!(..)`
diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs
index b4d94dc983fe..c17d73acc35e 100644
--- a/tests/lint_message_convention.rs
+++ b/tests/lint_message_convention.rs
@@ -84,7 +84,7 @@ fn lint_message_convention() {
                 .expect("failed to read dir")
                 .map(|direntry| direntry.unwrap().path())
         })
-        .filter(|file| matches!(file.extension().map(OsStr::to_str), Some(Some("stderr"))));
+        .filter(|file| file.extension().map(OsStr::to_str) == Some(Some("stderr")));
 
     // get all files that have any "bad lines" in them
     let bad_tests: Vec<Message> = tests
diff --git a/tests/ui-internal/if_chain_style.rs b/tests/ui-internal/if_chain_style.rs
index 8e871707aa8f..1bd8c4d61a10 100644
--- a/tests/ui-internal/if_chain_style.rs
+++ b/tests/ui-internal/if_chain_style.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::if_chain_style)]
-#![allow(clippy::no_effect)]
+#![allow(clippy::no_effect, clippy::equatable_if_let)]
 
 extern crate if_chain;
 
diff --git a/tests/ui/equatable_if_let.fixed b/tests/ui/equatable_if_let.fixed
index ba72cc237b4a..053667e82133 100644
--- a/tests/ui/equatable_if_let.fixed
+++ b/tests/ui/equatable_if_let.fixed
@@ -1,7 +1,7 @@
 // run-rustfix
 
-#![allow(unused_variables, dead_code)]
-#![warn(clippy::equatable_if_let)]
+#![allow(unused_variables, dead_code, clippy::redundant_pattern_matching, clippy::op_ref)]
+#![warn(clippy::equatable_if_let, clippy::equatable_matches)]
 
 use std::cmp::Ordering;
 
@@ -19,11 +19,13 @@ struct Struct {
     b: bool,
 }
 
+#[derive(Clone, Copy)]
 enum NotPartialEq {
     A,
     B,
 }
 
+#[derive(Clone, Copy)]
 enum NotStructuralEq {
     A,
     B,
@@ -35,6 +37,19 @@ impl PartialEq for NotStructuralEq {
     }
 }
 
+#[derive(PartialEq)]
+enum Generic<A, B> {
+    VA(A),
+    VB(B),
+    VC,
+}
+
+#[derive(PartialEq)]
+struct Generic2<A, B> {
+    a: A,
+    b: B,
+}
+
 fn main() {
     let a = 2;
     let b = 3;
@@ -43,6 +58,20 @@ fn main() {
     let e = Enum::UnitVariant;
     let f = NotPartialEq::A;
     let g = NotStructuralEq::A;
+    let h: Generic<Enum, NotPartialEq> = Generic::VC;
+    let i: Generic<Enum, NotStructuralEq> = 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
 
@@ -54,6 +83,24 @@ fn main() {
     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
 
@@ -63,7 +110,21 @@ fn main() {
     if let Struct { a, b: false } = d {}
     if let Struct { a: 2, b: x } = d {}
     if let NotPartialEq::A = f {}
-    if g == NotStructuralEq::A {}
+    if let NotStructuralEq::A = g {}
     if let Some(NotPartialEq::A) = Some(f) {}
-    if Some(g) == Some(NotStructuralEq::A) {}
+    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/equatable_if_let.rs b/tests/ui/equatable_if_let.rs
index 12526ca193db..7c2d8cf9d919 100644
--- a/tests/ui/equatable_if_let.rs
+++ b/tests/ui/equatable_if_let.rs
@@ -1,7 +1,7 @@
 // run-rustfix
 
-#![allow(unused_variables, dead_code)]
-#![warn(clippy::equatable_if_let)]
+#![allow(unused_variables, dead_code, clippy::redundant_pattern_matching, clippy::op_ref)]
+#![warn(clippy::equatable_if_let, clippy::equatable_matches)]
 
 use std::cmp::Ordering;
 
@@ -19,11 +19,13 @@ struct Struct {
     b: bool,
 }
 
+#[derive(Clone, Copy)]
 enum NotPartialEq {
     A,
     B,
 }
 
+#[derive(Clone, Copy)]
 enum NotStructuralEq {
     A,
     B,
@@ -35,6 +37,19 @@ impl PartialEq for NotStructuralEq {
     }
 }
 
+#[derive(PartialEq)]
+enum Generic<A, B> {
+    VA(A),
+    VB(B),
+    VC,
+}
+
+#[derive(PartialEq)]
+struct Generic2<A, B> {
+    a: A,
+    b: B,
+}
+
 fn main() {
     let a = 2;
     let b = 3;
@@ -43,6 +58,20 @@ fn main() {
     let e = Enum::UnitVariant;
     let f = NotPartialEq::A;
     let g = NotStructuralEq::A;
+    let h: Generic<Enum, NotPartialEq> = Generic::VC;
+    let i: Generic<Enum, NotStructuralEq> = 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
 
@@ -54,6 +83,30 @@ fn main() {
     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
 
@@ -65,5 +118,19 @@ fn main() {
     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/equatable_if_let.stderr b/tests/ui/equatable_if_let.stderr
index 79ef919384df..993974906df7 100644
--- a/tests/ui/equatable_if_let.stderr
+++ b/tests/ui/equatable_if_let.stderr
@@ -1,5 +1,5 @@
 error: this pattern matching can be expressed using equality
-  --> $DIR/equatable_if_let.rs:49:8
+  --> $DIR/equatable_if_let.rs:78:8
    |
 LL |     if let 2 = a {}
    |        ^^^^^^^^^ help: try: `a == 2`
@@ -7,58 +7,145 @@ LL |     if let 2 = a {}
    = note: `-D clippy::equatable-if-let` implied by `-D warnings`
 
 error: this pattern matching can be expressed using equality
-  --> $DIR/equatable_if_let.rs:50:8
+  --> $DIR/equatable_if_let.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/equatable_if_let.rs:51:8
+  --> $DIR/equatable_if_let.rs:80:8
    |
 LL |     if let Some(2) = c {}
    |        ^^^^^^^^^^^^^^^ help: try: `c == Some(2)`
 
 error: this pattern matching can be expressed using equality
-  --> $DIR/equatable_if_let.rs:52:8
+  --> $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:53:8
+  --> $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:54:8
+  --> $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:55:8
+  --> $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:56:8
+  --> $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:66:8
+  --> $DIR/equatable_if_let.rs:86:8
    |
-LL |     if let NotStructuralEq::A = g {}
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A`
+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:68:8
+  --> $DIR/equatable_if_let.rs:87:8
    |
-LL |     if let Some(NotStructuralEq::A) = Some(g) {}
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)`
+LL |     if let Generic::VA(Enum::UnitVariant) = i {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i == Generic::VA(Enum::UnitVariant)`
 
-error: aborting due to 10 previous errors
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:88: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
+   |
+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
+   |
+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)`
+   |
+   = 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