]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/matches.rs
modify code
[rust.git] / clippy_lints / src / matches.rs
index 5fa8f249e701e91d9b3cadf574f27ab873e0154b..2579404fb18cc5b152fd8448903475d4e1ba5bbf 100644 (file)
@@ -2,16 +2,17 @@
 use clippy_utils::diagnostics::{
     multispan_sugg, span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then,
 };
-use clippy_utils::higher;
+use clippy_utils::macros::{is_panic, root_macro_call};
 use clippy_utils::source::{expr_block, indent_of, snippet, snippet_block, snippet_opt, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item, match_type, peel_mid_ty_refs};
 use clippy_utils::visitors::is_local_used;
 use clippy_utils::{
-    get_parent_expr, is_expn_of, is_lang_ctor, is_lint_allowed, is_refutable, is_unit_expr, is_wild, meets_msrv, msrvs,
+    get_parent_expr, is_lang_ctor, is_lint_allowed, is_refutable, is_unit_expr, is_wild, meets_msrv, msrvs,
     path_to_local, path_to_local_id, peel_blocks, peel_hir_pat_refs, peel_n_hir_expr_refs, recurse_or_patterns,
     strip_pat_refs,
 };
+use clippy_utils::{higher, peel_blocks_with_stmt};
 use clippy_utils::{paths, search_same, SpanlessEq, SpanlessHash};
 use core::iter::{once, ExactSizeIterator};
 use if_chain::if_chain;
     Mutability, Node, Pat, PatKind, PathSegment, QPath, RangeEnd, TyKind,
 };
 use rustc_hir::{HirIdMap, HirIdSet};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty, TyS, VariantDef};
 use rustc_semver::RustcVersion;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::{Span, Spanned};
-use rustc_span::sym;
+use rustc_span::{sym, symbol::kw};
 use std::cmp::Ordering;
 use std::collections::hash_map::Entry;
 
@@ -960,13 +961,13 @@ fn check_wild_err_arm<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm
                 let path_str = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false));
                 if path_str == "Err" {
                     let mut matching_wild = inner.iter().any(is_wild);
-                    let mut ident_bind_name = String::from("_");
+                    let mut ident_bind_name = kw::Underscore;
                     if !matching_wild {
                         // Looking for unused bindings (i.e.: `_e`)
                         for pat in inner.iter() {
                             if let PatKind::Binding(_, id, ident, None) = pat.kind {
                                 if ident.as_str().starts_with('_') && !is_local_used(cx, arm.body, id) {
-                                    ident_bind_name = ident.name.as_str().to_string();
+                                    ident_bind_name = ident.name;
                                     matching_wild = true;
                                 }
                             }
@@ -974,13 +975,14 @@ fn check_wild_err_arm<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm
                     }
                     if_chain! {
                         if matching_wild;
-                        if is_panic_call(arm.body);
+                        if let Some(macro_call) = root_macro_call(peel_blocks_with_stmt(arm.body).span);
+                        if is_panic(cx, macro_call.def_id);
                         then {
                             // `Err(_)` or `Err(_e)` arm with `panic!` found
                             span_lint_and_note(cx,
                                 MATCH_WILD_ERR_ARM,
                                 arm.pat.span,
-                                &format!("`Err({})` matches all errors", &ident_bind_name),
+                                &format!("`Err({})` matches all errors", ident_bind_name),
                                 None,
                                 "match each error separately or use the error output, or use `.except(msg)` if the error case is unreachable",
                             );
@@ -997,7 +999,7 @@ enum CommonPrefixSearcher<'a> {
     Path(&'a [PathSegment<'a>]),
     Mixed,
 }
-impl CommonPrefixSearcher<'a> {
+impl<'a> CommonPrefixSearcher<'a> {
     fn with_path(&mut self, path: &'a [PathSegment<'a>]) {
         match path {
             [path @ .., _] => self.with_prefix(path),
@@ -1179,22 +1181,6 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
     };
 }
 
-// If the block contains only a `panic!` macro (as expression or statement)
-fn is_panic_call(expr: &Expr<'_>) -> bool {
-    // Unwrap any wrapping blocks
-    let span = if let ExprKind::Block(block, _) = expr.kind {
-        match (&block.expr, block.stmts.len(), block.stmts.first()) {
-            (&Some(exp), 0, _) => exp.span,
-            (&None, 1, Some(stmt)) => stmt.span,
-            _ => return false,
-        }
-    } else {
-        expr.span
-    };
-
-    is_expn_of(span, "panic").is_some() && is_expn_of(span, "unreachable").is_none()
-}
-
 fn check_match_ref_pats<'a, 'b, I>(cx: &LateContext<'_>, ex: &Expr<'_>, pats: I, expr: &Expr<'_>)
 where
     'b: 'a,
@@ -1790,7 +1776,7 @@ mod redundant_pattern_match {
     use rustc_errors::Applicability;
     use rustc_hir::LangItem::{OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk};
     use rustc_hir::{
-        intravisit::{walk_expr, ErasedMap, NestedVisitorMap, Visitor},
+        intravisit::{walk_expr, Visitor},
         Arm, Block, Expr, ExprKind, LangItem, MatchSource, Node, Pat, PatKind, QPath, UnOp,
     };
     use rustc_lint::LateContext;
@@ -1818,11 +1804,15 @@ pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
     /// Checks if the drop order for a type matters. Some std types implement drop solely to
     /// deallocate memory. For these types, and composites containing them, changing the drop order
     /// won't result in any observable side effects.
-    fn type_needs_ordered_drop(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
+    fn type_needs_ordered_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
         type_needs_ordered_drop_inner(cx, ty, &mut FxHashSet::default())
     }
 
-    fn type_needs_ordered_drop_inner(cx: &LateContext<'tcx>, ty: Ty<'tcx>, seen: &mut FxHashSet<Ty<'tcx>>) -> bool {
+    fn type_needs_ordered_drop_inner<'tcx>(
+        cx: &LateContext<'tcx>,
+        ty: Ty<'tcx>,
+        seen: &mut FxHashSet<Ty<'tcx>>,
+    ) -> bool {
         if !seen.insert(ty) {
             return false;
         }
@@ -1884,17 +1874,12 @@ fn try_get_generic_ty(ty: Ty<'_>, index: usize) -> Option<Ty<'_>> {
 
     // Checks if there are any temporaries created in the given expression for which drop order
     // matters.
-    fn temporaries_need_ordered_drop(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
+    fn temporaries_need_ordered_drop<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
         struct V<'a, 'tcx> {
             cx: &'a LateContext<'tcx>,
             res: bool,
         }
         impl<'a, 'tcx> Visitor<'tcx> for V<'a, 'tcx> {
-            type Map = ErasedMap<'tcx>;
-            fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
-                NestedVisitorMap::None
-            }
-
             fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
                 match expr.kind {
                     // Taking the reference of a value leaves a temporary
@@ -1924,7 +1909,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
                     },
                     // Method calls can take self by reference.
                     // e.g. In `String::new().len()` the string is a temporary value.
-                    ExprKind::MethodCall(_, _, [self_arg, args @ ..], _) => {
+                    ExprKind::MethodCall(_, [self_arg, args @ ..], _) => {
                         if !matches!(self_arg.kind, ExprKind::Path(_)) {
                             let self_by_ref = self
                                 .cx
@@ -2035,7 +2020,7 @@ fn find_sugg_for_if_let<'tcx>(
         // check that `while_let_on_iterator` lint does not trigger
         if_chain! {
             if keyword == "while";
-            if let ExprKind::MethodCall(method_path, _, _, _) = let_expr.kind;
+            if let ExprKind::MethodCall(method_path, _, _) = let_expr.kind;
             if method_path.ident.name == sym::next;
             if is_trait_method(cx, let_expr, sym::Iterator);
             then {