]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/pattern_type_mismatch.rs
Rollup merge of #88860 - nbdd0121:panic, r=m-ou-se
[rust.git] / clippy_lints / src / pattern_type_mismatch.rs
index 5539331d0460be96f00928833e1eb1300f5f3935..e7bc24465908b43851b87e2af2483e6ac7758028 100644 (file)
@@ -1,6 +1,7 @@
-use crate::utils::{last_path_segment, span_lint_and_help};
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::last_path_segment;
 use rustc_hir::{
-    intravisit, Body, Expr, ExprKind, FieldPat, FnDecl, HirId, LocalSource, MatchSource, Mutability, Pat, PatKind,
+    intravisit, Body, Expr, ExprKind, FnDecl, HirId, LocalSource, MatchSource, Mutability, Pat, PatField, PatKind,
     QPath, Stmt, StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -9,9 +10,11 @@
 use rustc_middle::ty::{AdtDef, FieldDef, Ty, TyKind, VariantDef};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::Span;
+use std::iter;
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for patterns that aren't exact representations of the types
+    /// ### What it does
+    /// Checks for patterns that aren't exact representations of the types
     /// they are applied to.
     ///
     /// To satisfy this lint, you will have to adjust either the expression that is matched
     /// this lint can still be used to highlight areas of interest and ensure a good understanding
     /// of ownership semantics.
     ///
-    /// **Why is this bad?** It isn't bad in general. But in some contexts it can be desirable
+    /// ### Why is this bad?
+    /// It isn't bad in general. But in some contexts it can be desirable
     /// because it increases ownership hints in the code, and will guard against some changes
     /// in ownership.
     ///
-    /// **Known problems:** None.
-    ///
-    /// **Example:**
-    ///
+    /// ### Example
     /// This example shows the basic adjustments necessary to satisfy the lint. Note how
     /// the matched expression is explicitly dereferenced with `*` and the `inner` variable
     /// is bound to a shared borrow via `ref inner`.
@@ -85,7 +86,7 @@
 
 impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
-        if let StmtKind::Local(ref local) = stmt.kind {
+        if let StmtKind::Local(local) = stmt.kind {
             if let Some(init) = &local.init {
                 if let Some(init_ty) = cx.typeck_results().node_type_opt(init.hir_id) {
                     let pat = &local.pat;
@@ -103,22 +104,25 @@ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if let ExprKind::Match(ref expr, arms, source) = expr.kind {
-            match source {
-                MatchSource::Normal | MatchSource::IfLetDesugar { .. } | MatchSource::WhileLetDesugar => {
-                    if let Some(expr_ty) = cx.typeck_results().node_type_opt(expr.hir_id) {
-                        'pattern_checks: for arm in arms {
-                            let pat = &arm.pat;
-                            if in_external_macro(cx.sess(), pat.span) {
-                                continue 'pattern_checks;
-                            }
-                            if apply_lint(cx, pat, expr_ty, DerefPossible::Possible) {
-                                break 'pattern_checks;
-                            }
-                        }
+        if let ExprKind::Match(scrutinee, arms, MatchSource::Normal) = expr.kind {
+            if let Some(expr_ty) = cx.typeck_results().node_type_opt(scrutinee.hir_id) {
+                'pattern_checks: for arm in arms {
+                    let pat = &arm.pat;
+                    if in_external_macro(cx.sess(), pat.span) {
+                        continue 'pattern_checks;
                     }
-                },
-                _ => (),
+                    if apply_lint(cx, pat, expr_ty, DerefPossible::Possible) {
+                        break 'pattern_checks;
+                    }
+                }
+            }
+        }
+        if let ExprKind::Let(let_pat, let_expr, _) = expr.kind {
+            if let Some(expr_ty) = cx.typeck_results().node_type_opt(let_expr.hir_id) {
+                if in_external_macro(cx.sess(), let_pat.span) {
+                    return;
+                }
+                apply_lint(cx, let_pat, expr_ty, DerefPossible::Possible);
             }
         }
     }
@@ -133,8 +137,8 @@ fn check_fn(
         hir_id: HirId,
     ) {
         if let Some(fn_sig) = cx.typeck_results().liberated_fn_sigs().get(hir_id) {
-            for (param, ty) in body.params.iter().zip(fn_sig.inputs().iter()) {
-                apply_lint(cx, &param.pat, ty, DerefPossible::Impossible);
+            for (param, ty) in iter::zip(body.params, fn_sig.inputs()) {
+                apply_lint(cx, param.pat, ty, DerefPossible::Impossible);
             }
         }
     }
@@ -186,7 +190,7 @@ fn find_first_mismatch<'tcx>(
     ty: Ty<'tcx>,
     level: Level,
 ) -> Option<(Span, Mutability, Level)> {
-    if let PatKind::Ref(ref sub_pat, _) = pat.kind {
+    if let PatKind::Ref(sub_pat, _) = pat.kind {
         if let TyKind::Ref(_, sub_ty, _) = ty.kind() {
             return find_first_mismatch(cx, sub_pat, sub_ty, Level::Lower);
         }
@@ -198,8 +202,8 @@ fn find_first_mismatch<'tcx>(
         }
     }
 
-    if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.kind {
-        if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind() {
+    if let PatKind::Struct(ref qpath, field_pats, _) = pat.kind {
+        if let TyKind::Adt(adt_def, substs_ref) = ty.kind() {
             if let Some(variant) = get_variant(adt_def, qpath) {
                 let field_defs = &variant.fields;
                 return find_first_mismatch_in_struct(cx, field_pats, field_defs, substs_ref);
@@ -207,8 +211,8 @@ fn find_first_mismatch<'tcx>(
         }
     }
 
-    if let PatKind::TupleStruct(ref qpath, ref pats, _) = pat.kind {
-        if let TyKind::Adt(ref adt_def, ref substs_ref) = ty.kind() {
+    if let PatKind::TupleStruct(ref qpath, pats, _) = pat.kind {
+        if let TyKind::Adt(adt_def, substs_ref) = ty.kind() {
             if let Some(variant) = get_variant(adt_def, qpath) {
                 let field_defs = &variant.fields;
                 let ty_iter = field_defs.iter().map(|field_def| field_def.ty(cx.tcx, substs_ref));
@@ -217,7 +221,7 @@ fn find_first_mismatch<'tcx>(
         }
     }
 
-    if let PatKind::Tuple(ref pats, _) = pat.kind {
+    if let PatKind::Tuple(pats, _) = pat.kind {
         if let TyKind::Tuple(..) = ty.kind() {
             return find_first_mismatch_in_tuple(cx, pats, ty.tuple_fields());
         }
@@ -256,7 +260,7 @@ fn get_variant<'a>(adt_def: &'a AdtDef, qpath: &QPath<'_>) -> Option<&'a Variant
 
 fn find_first_mismatch_in_tuple<'tcx, I>(
     cx: &LateContext<'tcx>,
-    pats: &[&Pat<'_>],
+    pats: &[Pat<'_>],
     ty_iter_src: I,
 ) -> Option<(Span, Mutability, Level)>
 where
@@ -281,7 +285,7 @@ fn find_first_mismatch_in_tuple<'tcx, I>(
 
 fn find_first_mismatch_in_struct<'tcx>(
     cx: &LateContext<'tcx>,
-    field_pats: &[FieldPat<'_>],
+    field_pats: &[PatField<'_>],
     field_defs: &[FieldDef],
     substs_ref: SubstsRef<'tcx>,
 ) -> Option<(Span, Mutability, Level)> {