about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/equatable_if_let.rs64
-rw-r--r--tests/ui/equatable_if_let.rs7
2 files changed, 47 insertions, 24 deletions
diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs
index ba615c8c164..6f26195d105 100644
--- a/clippy_lints/src/equatable_if_let.rs
+++ b/clippy_lints/src/equatable_if_let.rs
@@ -68,31 +68,47 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         if !in_external_macro(cx.sess(), expr.span)
             && let ExprKind::Let(let_expr) = expr.kind
-            && unary_pattern(let_expr.pat)
-            && let exp_ty = cx.typeck_results().expr_ty(let_expr.init)
-            && let pat_ty = cx.typeck_results().pat_ty(let_expr.pat)
-            && is_structural_partial_eq(cx, exp_ty, pat_ty) {
+            && unary_pattern(let_expr.pat) {
+            let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
+            let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
             let mut applicability = Applicability::MachineApplicable;
-            let pat_str = match let_expr.pat.kind {
-                PatKind::Struct(..) => format!(
-                    "({})",
-                    snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
-                ),
-                _ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(),
-            };
-            span_lint_and_sugg(
-                cx,
-                EQUATABLE_IF_LET,
-                expr.span,
-                "this pattern matching can be expressed using equality",
-                "try",
-                format!(
-                    "{} == {}",
-                    snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
-                    pat_str,
-                ),
-                applicability,
-            );
+
+            if is_structural_partial_eq(cx, exp_ty, pat_ty) {
+                let pat_str = match let_expr.pat.kind {
+                    PatKind::Struct(..) => format!(
+                        "({})",
+                        snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
+                    ),
+                    _ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(),
+                };
+                span_lint_and_sugg(
+                    cx,
+                    EQUATABLE_IF_LET,
+                    expr.span,
+                    "this pattern matching can be expressed using equality",
+                    "try",
+                    format!(
+                        "{} == {}",
+                        snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
+                        pat_str,
+                    ),
+                    applicability,
+                );
+            } else {
+                span_lint_and_sugg(
+                    cx, 
+                    EQUATABLE_IF_LET,
+                    expr.span,
+                    "this pattern matching can be expressed using `matches!`", 
+                    "try", 
+                    format!(
+                        "matches!({}, {})",
+                        snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
+                        snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
+                    ), 
+                    applicability,
+                )
+            }
         }
     }
 }
diff --git a/tests/ui/equatable_if_let.rs b/tests/ui/equatable_if_let.rs
index 8c467d14d2a..c3626c081dd 100644
--- a/tests/ui/equatable_if_let.rs
+++ b/tests/ui/equatable_if_let.rs
@@ -23,6 +23,11 @@ struct Struct {
     b: bool,
 }
 
+struct NoPartialEqStruct {
+    a: i32,
+    b: bool,
+}
+
 enum NotPartialEq {
     A,
     B,
@@ -47,6 +52,7 @@ fn main() {
     let e = Enum::UnitVariant;
     let f = NotPartialEq::A;
     let g = NotStructuralEq::A;
+    let h = NoPartialEqStruct { a: 2, b: false };
 
     // true
 
@@ -70,6 +76,7 @@ fn main() {
     if let NotStructuralEq::A = g {}
     if let Some(NotPartialEq::A) = Some(f) {}
     if let Some(NotStructuralEq::A) = Some(g) {}
+    if let NoPartialEqStruct { a: 2, b: false } = h {}
 
     macro_rules! m1 {
         (x) => {