]> git.proxmox.com Git - rustc.git/blobdiff - src/tools/clippy/clippy_lints/src/equatable_if_let.rs
bump version to 1.79.0+dfsg1-1~bpo12+pve2
[rustc.git] / src / tools / clippy / clippy_lints / src / equatable_if_let.rs
index ef1216358dd97eb8eaa6dd00ddfbf3983c056e85..37442bf3e2867ab32429f9f9f0b67a4200033f41 100644 (file)
@@ -1,12 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::implements_trait;
-use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Pat, PatKind};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Ty;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -46,12 +46,16 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
         pats.iter().all(unary_pattern)
     }
     match &pat.kind {
-        PatKind::Slice(_, _, _) | PatKind::Range(_, _, _) | PatKind::Binding(..) | PatKind::Wild | PatKind::Or(_) => {
-            false
-        },
+        PatKind::Slice(_, _, _)
+        | PatKind::Range(_, _, _)
+        | PatKind::Binding(..)
+        | PatKind::Wild
+        | PatKind::Never
+        | PatKind::Or(_)
+        | PatKind::Err(_) => false,
         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::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a),
+        PatKind::Ref(x, _) | PatKind::Box(x) | PatKind::Deref(x) => unary_pattern(x),
         PatKind::Path(_) | PatKind::Lit(_) => true,
     }
 }
@@ -66,21 +70,23 @@ fn is_structural_partial_eq<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: T
 
 impl<'tcx> LateLintPass<'tcx> for PatternEquality {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        if_chain! {
-            if let ExprKind::Let(let_expr) = expr.kind;
-            if unary_pattern(let_expr.pat);
+        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);
-            if is_structural_partial_eq(cx, exp_ty, pat_ty);
-            then {
+            let mut applicability = Applicability::MachineApplicable;
 
-                let mut applicability = Applicability::MachineApplicable;
+            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(),
+                    _ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability)
+                        .0
+                        .to_string(),
                 };
                 span_lint_and_sugg(
                     cx,
@@ -89,9 +95,22 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
                     "this pattern matching can be expressed using equality",
                     "try",
                     format!(
-                        "{} == {}",
+                        "{} == {pat_str}",
                         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,
                 );