about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJason Newcomb <jsnewcomb@pm.me>2021-04-07 16:19:25 -0400
committerJason Newcomb <jsnewcomb@pm.me>2021-04-15 19:27:25 -0400
commitf6c5d8d599070bacad800ac7014fa3a6f140eadc (patch)
tree012bf8d18f3e1d02ce4ed8fbf6c77f4f2c560030
parentb1c675f3fc682201cdb28719133285b878e2d157 (diff)
downloadrust-f6c5d8d599070bacad800ac7014fa3a6f140eadc.tar.gz
rust-f6c5d8d599070bacad800ac7014fa3a6f140eadc.zip
Remove all usages of `match_path`, `match_qpath` and `match_path_ast` except the `author` lint.
Add note to fix `MATCH_TYPE_ON_DIAG_ITEM`
Add false negative test for `uninit_assumed_init`
-rw-r--r--clippy_lints/src/assertions_on_constants.rs5
-rw-r--r--clippy_lints/src/excessive_bools.rs6
-rw-r--r--clippy_lints/src/implicit_hasher.rs7
-rw-r--r--clippy_lints/src/implicit_saturating_sub.rs43
-rw-r--r--clippy_lints/src/infinite_iter.rs4
-rw-r--r--clippy_lints/src/map_identity.rs4
-rw-r--r--clippy_lints/src/matches.rs24
-rw-r--r--clippy_lints/src/methods/filter_map_identity.rs12
-rw-r--r--clippy_lints/src/methods/flat_map_identity.rs18
-rw-r--r--clippy_lints/src/methods/from_iter_instead_of_collect.rs11
-rw-r--r--clippy_lints/src/methods/manual_saturating_arithmetic.rs6
-rw-r--r--clippy_lints/src/methods/mod.rs2
-rw-r--r--clippy_lints/src/methods/uninit_assumed_init.rs5
-rw-r--r--clippy_lints/src/methods/unnecessary_filter_map.rs2
-rw-r--r--clippy_lints/src/misc.rs18
-rw-r--r--clippy_lints/src/ptr.rs17
-rw-r--r--clippy_lints/src/question_mark.rs11
-rw-r--r--clippy_lints/src/returns.rs7
-rw-r--r--clippy_lints/src/slow_vector_initialization.rs69
-rw-r--r--clippy_lints/src/transmuting_null.rs23
-rw-r--r--clippy_lints/src/types/borrowed_box.rs9
-rw-r--r--clippy_lints/src/unnecessary_wraps.rs10
-rw-r--r--clippy_lints/src/utils/internal_lints.rs14
-rw-r--r--clippy_utils/src/lib.rs89
-rw-r--r--clippy_utils/src/paths.rs12
-rw-r--r--doc/adding_lints.md2
-rw-r--r--tests/ui-internal/collapsible_span_lint_calls.fixed48
-rw-r--r--tests/ui-internal/collapsible_span_lint_calls.rs48
-rw-r--r--tests/ui-internal/collapsible_span_lint_calls.stderr10
-rw-r--r--tests/ui-internal/match_type_on_diag_item.rs21
-rw-r--r--tests/ui-internal/match_type_on_diag_item.stderr30
-rw-r--r--tests/ui/repl_uninit.rs4
-rw-r--r--tests/ui/uninit.rs5
-rw-r--r--tests/ui/uninit.stderr8
34 files changed, 269 insertions, 335 deletions
diff --git a/clippy_lints/src/assertions_on_constants.rs b/clippy_lints/src/assertions_on_constants.rs
index a0993bb6913..c565e29d078 100644
--- a/clippy_lints/src/assertions_on_constants.rs
+++ b/clippy_lints/src/assertions_on_constants.rs
@@ -127,10 +127,9 @@ fn match_assert_with_message<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>)
             _ => &block.expr,
         };
         // function call
-        if let Some(args) = match_panic_call(cx, begin_panic_call);
-        if args.len() == 1;
+        if let Some(arg) = match_panic_call(cx, begin_panic_call);
         // bind the second argument of the `assert!` macro if it exists
-        if let panic_message = snippet_opt(cx, args[0].span);
+        if let panic_message = snippet_opt(cx, arg.span);
         // second argument of begin_panic is irrelevant
         // as is the second match arm
         then {
diff --git a/clippy_lints/src/excessive_bools.rs b/clippy_lints/src/excessive_bools.rs
index 249ee27330b..4e2dbf005d5 100644
--- a/clippy_lints/src/excessive_bools.rs
+++ b/clippy_lints/src/excessive_bools.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::{in_macro, match_path_ast};
+use clippy_utils::in_macro;
 use rustc_ast::ast::{AssocItemKind, Extern, FnKind, FnSig, ImplKind, Item, ItemKind, TraitKind, Ty, TyKind};
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -126,7 +126,9 @@ impl_lint_pass!(ExcessiveBools => [STRUCT_EXCESSIVE_BOOLS, FN_PARAMS_EXCESSIVE_B
 
 fn is_bool_ty(ty: &Ty) -> bool {
     if let TyKind::Path(None, path) = &ty.kind {
-        return match_path_ast(path, &["bool"]);
+        if let [name] = path.segments.as_slice() {
+            return name.ident.name == sym::bool;
+        }
     }
     false
 }
diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs
index 77a38544edc..03fe0d16d48 100644
--- a/clippy_lints/src/implicit_hasher.rs
+++ b/clippy_lints/src/implicit_hasher.rs
@@ -22,7 +22,7 @@ use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
 use clippy_utils::paths;
 use clippy_utils::source::{snippet, snippet_opt};
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{differing_macro_contexts, match_path};
+use clippy_utils::{differing_macro_contexts, match_def_path};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for public `impl` or `fn` missing generalization
@@ -333,12 +333,13 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
             if let ExprKind::Call(fun, args) = e.kind;
             if let ExprKind::Path(QPath::TypeRelative(ty, method)) = fun.kind;
             if let TyKind::Path(QPath::Resolved(None, ty_path)) = ty.kind;
+            if let Some(ty_did) = ty_path.res.opt_def_id();
             then {
                 if !TyS::same_type(self.target.ty(), self.maybe_typeck_results.unwrap().expr_ty(e)) {
                     return;
                 }
 
-                if match_path(ty_path, &paths::HASHMAP) {
+                if match_def_path(self.cx, ty_did, &paths::HASHMAP) {
                     if method.ident.name == sym::new {
                         self.suggestions
                             .insert(e.span, "HashMap::default()".to_string());
@@ -351,7 +352,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
                             ),
                         );
                     }
-                } else if match_path(ty_path, &paths::HASHSET) {
+                } else if match_def_path(self.cx, ty_did, &paths::HASHSET) {
                     if method.ident.name == sym::new {
                         self.suggestions
                             .insert(e.span, "HashSet::default()".to_string());
diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs
index cba3183e869..4069a685ea0 100644
--- a/clippy_lints/src/implicit_saturating_sub.rs
+++ b/clippy_lints/src/implicit_saturating_sub.rs
@@ -1,9 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{in_macro, match_qpath, SpanlessEq};
+use clippy_utils::{in_macro, SpanlessEq};
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, StmtKind};
+use rustc_hir::{lang_items::LangItem, BinOpKind, Expr, ExprKind, QPath, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
@@ -87,7 +87,13 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
 
                 // Get the variable name
                 let var_name = ares_path.segments[0].ident.name.as_str();
-                const INT_TYPES: [&str; 5] = ["i8", "i16", "i32", "i64", "i128"];
+                const INT_TYPES: [LangItem; 5] = [
+                    LangItem::I8,
+                    LangItem::I16,
+                    LangItem::I32,
+                    LangItem::I64,
+                    LangItem::Isize
+                ];
 
                 match cond_num_val.kind {
                     ExprKind::Lit(ref cond_lit) => {
@@ -99,17 +105,30 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
                             };
                         }
                     },
-                    ExprKind::Path(ref cond_num_path) => {
-                        if INT_TYPES.iter().any(|int_type| match_qpath(cond_num_path, &[int_type, "MIN"])) {
-                            print_lint_and_sugg(cx, &var_name, expr);
-                        };
+                    ExprKind::Path(QPath::TypeRelative(_, name)) => {
+                        if_chain! {
+                            if name.ident.as_str() == "MIN";
+                            if let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id);
+                            if let Some(impl_id) = cx.tcx.impl_of_method(const_id);
+                            let mut int_ids = INT_TYPES.iter().filter_map(|&ty| cx.tcx.lang_items().require(ty).ok());
+                            if int_ids.any(|int_id| int_id == impl_id);
+                            then {
+                                print_lint_and_sugg(cx, &var_name, expr)
+                            }
+                        }
                     },
-                    ExprKind::Call(func, _) => {
-                        if let ExprKind::Path(ref cond_num_path) = func.kind {
-                            if INT_TYPES.iter().any(|int_type| match_qpath(cond_num_path, &[int_type, "min_value"])) {
-                                print_lint_and_sugg(cx, &var_name, expr);
+                    ExprKind::Call(func, []) => {
+                        if_chain! {
+                            if let ExprKind::Path(QPath::TypeRelative(_, name)) = func.kind;
+                            if name.ident.as_str() == "min_value";
+                            if let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id);
+                            if let Some(impl_id) = cx.tcx.impl_of_method(func_id);
+                            let mut int_ids = INT_TYPES.iter().filter_map(|&ty| cx.tcx.lang_items().require(ty).ok());
+                            if int_ids.any(|int_id| int_id == impl_id);
+                            then {
+                                print_lint_and_sugg(cx, &var_name, expr)
                             }
-                        };
+                        }
                     },
                     _ => (),
                 }
diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs
index bbb4ddc613a..afee20ce43e 100644
--- a/clippy_lints/src/infinite_iter.rs
+++ b/clippy_lints/src/infinite_iter.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::{implements_trait, match_type};
-use clippy_utils::{get_trait_def_id, higher, match_qpath, paths};
+use clippy_utils::{get_trait_def_id, higher, is_qpath_def_path, paths};
 use rustc_hir::{BorrowKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -163,7 +163,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
         ExprKind::Box(e) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e),
         ExprKind::Call(path, _) => {
             if let ExprKind::Path(ref qpath) = path.kind {
-                match_qpath(qpath, &paths::REPEAT).into()
+                is_qpath_def_path(cx, qpath, path.hir_id, &paths::ITER_REPEAT).into()
             } else {
                 Finite
             }
diff --git a/clippy_lints/src/map_identity.rs b/clippy_lints/src/map_identity.rs
index e7719e7663d..41cda23510e 100644
--- a/clippy_lints/src/map_identity.rs
+++ b/clippy_lints/src/map_identity.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{is_adjusted, is_trait_method, match_path, match_var, paths, remove_blocks};
+use clippy_utils::{is_adjusted, is_qpath_def_path, is_trait_method, match_var, paths, remove_blocks};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{Body, Expr, ExprKind, Pat, PatKind, QPath, StmtKind};
@@ -80,7 +80,7 @@ fn get_map_argument<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a
 fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     match expr.kind {
         ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)),
-        ExprKind::Path(QPath::Resolved(_, path)) => match_path(path, &paths::STD_CONVERT_IDENTITY),
+        ExprKind::Path(ref path) => is_qpath_def_path(cx, path, expr.hir_id, &paths::CONVERT_IDENTITY),
         _ => false,
     }
 }
diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs
index 30091e0e2d7..8f1112cff7b 100644
--- a/clippy_lints/src/matches.rs
+++ b/clippy_lints/src/matches.rs
@@ -1701,7 +1701,7 @@ mod redundant_pattern_match {
     use super::REDUNDANT_PATTERN_MATCHING;
     use clippy_utils::diagnostics::span_lint_and_then;
     use clippy_utils::source::snippet;
-    use clippy_utils::{is_lang_ctor, is_trait_method, match_qpath, paths};
+    use clippy_utils::{is_lang_ctor, is_qpath_def_path, is_trait_method, paths};
     use if_chain::if_chain;
     use rustc_ast::ast::LitKind;
     use rustc_errors::Applicability;
@@ -1735,8 +1735,8 @@ mod redundant_pattern_match {
             kind = &inner.kind;
         }
         let good_method = match kind {
-            PatKind::TupleStruct(ref path, patterns, _) if patterns.len() == 1 => {
-                if let PatKind::Wild = patterns[0].kind {
+            PatKind::TupleStruct(ref path, [sub_pat], _) => {
+                if let PatKind::Wild = sub_pat.kind {
                     if is_lang_ctor(cx, path, ResultOk) {
                         "is_ok()"
                     } else if is_lang_ctor(cx, path, ResultErr) {
@@ -1745,9 +1745,9 @@ mod redundant_pattern_match {
                         "is_some()"
                     } else if is_lang_ctor(cx, path, PollReady) {
                         "is_ready()"
-                    } else if match_qpath(path, &paths::IPADDR_V4) {
+                    } else if is_qpath_def_path(cx, path, sub_pat.hir_id, &paths::IPADDR_V4) {
                         "is_ipv4()"
-                    } else if match_qpath(path, &paths::IPADDR_V6) {
+                    } else if is_qpath_def_path(cx, path, sub_pat.hir_id, &paths::IPADDR_V6) {
                         "is_ipv6()"
                     } else {
                         return;
@@ -1821,6 +1821,7 @@ mod redundant_pattern_match {
                 ) if patterns_left.len() == 1 && patterns_right.len() == 1 => {
                     if let (PatKind::Wild, PatKind::Wild) = (&patterns_left[0].kind, &patterns_right[0].kind) {
                         find_good_method_for_match(
+                            cx,
                             arms,
                             path_left,
                             path_right,
@@ -1831,6 +1832,7 @@ mod redundant_pattern_match {
                         )
                         .or_else(|| {
                             find_good_method_for_match(
+                                cx,
                                 arms,
                                 path_left,
                                 path_right,
@@ -1850,6 +1852,7 @@ mod redundant_pattern_match {
                 {
                     if let PatKind::Wild = patterns[0].kind {
                         find_good_method_for_match(
+                            cx,
                             arms,
                             path_left,
                             path_right,
@@ -1860,6 +1863,7 @@ mod redundant_pattern_match {
                         )
                         .or_else(|| {
                             find_good_method_for_match(
+                                cx,
                                 arms,
                                 path_left,
                                 path_right,
@@ -1900,7 +1904,9 @@ mod redundant_pattern_match {
         }
     }
 
+    #[allow(clippy::too_many_arguments)]
     fn find_good_method_for_match<'a>(
+        cx: &LateContext<'_>,
         arms: &[Arm<'_>],
         path_left: &QPath<'_>,
         path_right: &QPath<'_>,
@@ -1909,9 +1915,13 @@ mod redundant_pattern_match {
         should_be_left: &'a str,
         should_be_right: &'a str,
     ) -> Option<&'a str> {
-        let body_node_pair = if match_qpath(path_left, expected_left) && match_qpath(path_right, expected_right) {
+        let body_node_pair = if is_qpath_def_path(cx, path_left, arms[0].pat.hir_id, expected_left)
+            && is_qpath_def_path(cx, path_right, arms[1].pat.hir_id, expected_right)
+        {
             (&(*arms[0].body).kind, &(*arms[1].body).kind)
-        } else if match_qpath(path_right, expected_left) && match_qpath(path_left, expected_right) {
+        } else if is_qpath_def_path(cx, path_right, arms[1].pat.hir_id, expected_left)
+            && is_qpath_def_path(cx, path_left, arms[0].pat.hir_id, expected_right)
+        {
             (&(*arms[1].body).kind, &(*arms[0].body).kind)
         } else {
             return None;
diff --git a/clippy_lints/src/methods/filter_map_identity.rs b/clippy_lints/src/methods/filter_map_identity.rs
index 3a61f4ccad7..403fe8d3546 100644
--- a/clippy_lints/src/methods/filter_map_identity.rs
+++ b/clippy_lints/src/methods/filter_map_identity.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{is_trait_method, match_qpath, path_to_local_id, paths};
+use clippy_utils::{is_expr_path_def_path, is_trait_method, path_to_local_id, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -33,14 +33,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg:
             }
         }
 
-        if_chain! {
-            if let hir::ExprKind::Path(ref qpath) = filter_map_arg.kind;
-
-            if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY);
-
-            then {
-                apply_lint("called `filter_map(std::convert::identity)` on an `Iterator`");
-            }
+        if is_expr_path_def_path(cx, filter_map_arg, &paths::CONVERT_IDENTITY) {
+            apply_lint("called `filter_map(std::convert::identity)` on an `Iterator`");
         }
     }
 }
diff --git a/clippy_lints/src/methods/flat_map_identity.rs b/clippy_lints/src/methods/flat_map_identity.rs
index dd613d0cd63..25f8434cb94 100644
--- a/clippy_lints/src/methods/flat_map_identity.rs
+++ b/clippy_lints/src/methods/flat_map_identity.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{is_trait_method, match_qpath, paths};
+use clippy_utils::{is_expr_path_def_path, is_trait_method, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -16,8 +16,6 @@ pub(super) fn check<'tcx>(
     flat_map_span: Span,
 ) {
     if is_trait_method(cx, expr, sym::Iterator) {
-        let arg_node = &flat_map_arg.kind;
-
         let apply_lint = |message: &str| {
             span_lint_and_sugg(
                 cx,
@@ -31,8 +29,8 @@ pub(super) fn check<'tcx>(
         };
 
         if_chain! {
-            if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node;
-            let body = cx.tcx.hir().body(*body_id);
+            if let hir::ExprKind::Closure(_, _, body_id, _, _) = flat_map_arg.kind;
+            let body = cx.tcx.hir().body(body_id);
 
             if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.kind;
             if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = body.value.kind;
@@ -45,14 +43,8 @@ pub(super) fn check<'tcx>(
             }
         }
 
-        if_chain! {
-            if let hir::ExprKind::Path(ref qpath) = arg_node;
-
-            if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY);
-
-            then {
-                apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`");
-            }
+        if is_expr_path_def_path(cx, flat_map_arg, &paths::CONVERT_IDENTITY) {
+            apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`");
         }
     }
 }
diff --git a/clippy_lints/src/methods/from_iter_instead_of_collect.rs b/clippy_lints/src/methods/from_iter_instead_of_collect.rs
index 707c54f7a3c..28d0e8cd4ae 100644
--- a/clippy_lints/src/methods/from_iter_instead_of_collect.rs
+++ b/clippy_lints/src/methods/from_iter_instead_of_collect.rs
@@ -1,26 +1,23 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::ty::implements_trait;
-use clippy_utils::{get_trait_def_id, match_qpath, paths, sugg};
+use clippy_utils::{is_expr_path_def_path, paths, sugg};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
-use rustc_hir::ExprKind;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::ty::Ty;
 use rustc_span::sym;
 
 use super::FROM_ITER_INSTEAD_OF_COLLECT;
 
-pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>], func_kind: &ExprKind<'_>) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>], func: &hir::Expr<'_>) {
     if_chain! {
-        if let hir::ExprKind::Path(path) = func_kind;
-        if match_qpath(path, &["from_iter"]);
+        if is_expr_path_def_path(cx, func, &paths::FROM_ITERATOR_METHOD);
         let ty = cx.typeck_results().expr_ty(expr);
         let arg_ty = cx.typeck_results().expr_ty(&args[0]);
-        if let Some(from_iter_id) = get_trait_def_id(cx, &paths::FROM_ITERATOR);
         if let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
 
-        if implements_trait(cx, ty, from_iter_id, &[]) && implements_trait(cx, arg_ty, iter_id, &[]);
+        if implements_trait(cx, arg_ty, iter_id, &[]);
         then {
             // `expr` implements `FromIterator` trait
             let iter_expr = sugg::Sugg::hir(cx, &args[0], "..").maybe_par();
diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs
index ecb8b72ef46..2fddea7068d 100644
--- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs
+++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::match_qpath;
+use clippy_utils::is_qpath_def_path;
 use clippy_utils::source::snippet_with_applicability;
 use if_chain::if_chain;
 use rustc_ast::ast;
@@ -94,11 +94,11 @@ fn is_min_or_max<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) -> Option<M
 
     // `std::T::MAX` `std::T::MIN` constants
     if let hir::ExprKind::Path(path) = &expr.kind {
-        if match_qpath(path, &["core", &ty_str, "MAX"][..]) {
+        if is_qpath_def_path(cx, path, expr.hir_id, &["core", &ty_str, "MAX"][..]) {
             return Some(MinMax::Max);
         }
 
-        if match_qpath(path, &["core", &ty_str, "MIN"][..]) {
+        if is_qpath_def_path(cx, path, expr.hir_id, &["core", &ty_str, "MIN"][..]) {
             return Some(MinMax::Min);
         }
     }
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index b2faaef0786..6c21ff0f6c2 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -1708,7 +1708,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
 
         match expr.kind {
             hir::ExprKind::Call(func, args) => {
-                from_iter_instead_of_collect::check(cx, expr, args, &func.kind);
+                from_iter_instead_of_collect::check(cx, expr, args, func);
             },
             hir::ExprKind::MethodCall(method_call, ref method_span, args, _) => {
                 or_fun_call::check(cx, expr, *method_span, &method_call.ident.as_str(), args);
diff --git a/clippy_lints/src/methods/uninit_assumed_init.rs b/clippy_lints/src/methods/uninit_assumed_init.rs
index 0ae65c0c01d..1a5894e48d1 100644
--- a/clippy_lints/src/methods/uninit_assumed_init.rs
+++ b/clippy_lints/src/methods/uninit_assumed_init.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{match_def_path, match_qpath, paths};
+use clippy_utils::{is_expr_path_def_path, match_def_path, paths};
 use if_chain::if_chain;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -12,8 +12,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
     if_chain! {
         if let hir::ExprKind::Call(callee, args) = recv.kind;
         if args.is_empty();
-        if let hir::ExprKind::Path(ref path) = callee.kind;
-        if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT);
+        if is_expr_path_def_path(cx, callee, &paths::MEM_MAYBEUNINIT_UNINIT);
         if !is_maybe_uninit_ty_valid(cx, cx.typeck_results().expr_ty_adjusted(expr));
         then {
             span_lint(
diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs
index 66255b77331..b61c4ffe9b3 100644
--- a/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -61,8 +61,6 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc
                     }
                     return (true, false);
                 }
-                // We don't know. It might do anything.
-                return (true, true);
             }
             (true, true)
         },
diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs
index d156c1d5bf4..0b0cd9be46c 100644
--- a/clippy_lints/src/misc.rs
+++ b/clippy_lints/src/misc.rs
@@ -20,8 +20,8 @@ use rustc_span::symbol::sym;
 use crate::consts::{constant, Constant};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    get_item_name, get_parent_expr, higher, in_constant, is_diag_trait_item, is_integer_const, iter_input_pats,
-    last_path_segment, match_qpath, unsext, SpanlessEq,
+    expr_path_res, get_item_name, get_parent_expr, higher, in_constant, is_diag_trait_item, is_integer_const,
+    iter_input_pats, last_path_segment, match_any_def_paths, paths, unsext, SpanlessEq,
 };
 
 declare_clippy_lint! {
@@ -564,13 +564,13 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left:
                 }
             )
         },
-        ExprKind::Call(path, v) if v.len() == 1 => {
-            if let ExprKind::Path(ref path) = path.kind {
-                if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"]) {
-                    (cx.typeck_results().expr_ty(&v[0]), snippet(cx, v[0].span, ".."))
-                } else {
-                    return;
-                }
+        ExprKind::Call(path, [arg]) => {
+            if expr_path_res(cx, path)
+                .opt_def_id()
+                .and_then(|id| match_any_def_paths(cx, id, &[&paths::FROM_STR_METHOD, &paths::FROM_FROM]))
+                .is_some()
+            {
+                (cx.typeck_results().expr_ty(arg), snippet(cx, arg.span, ".."))
             } else {
                 return;
             }
diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs
index 2ab1e958ec8..b0674f90678 100644
--- a/clippy_lints/src/ptr.rs
+++ b/clippy_lints/src/ptr.rs
@@ -4,7 +4,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_the
 use clippy_utils::ptr::get_spans;
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::{is_type_diagnostic_item, match_type, walk_ptrs_hir_ty};
-use clippy_utils::{is_allowed, match_def_path, paths};
+use clippy_utils::{expr_path_res, is_allowed, match_any_def_paths, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{
@@ -417,14 +417,11 @@ fn get_rptr_lm<'tcx>(ty: &'tcx Ty<'tcx>) -> Option<(&'tcx Lifetime, Mutability,
 }
 
 fn is_null_path(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    if_chain! {
-        if let ExprKind::Call(path, []) = expr.kind;
-        if let ExprKind::Path(ref qpath) = path.kind;
-        if let Some(fn_def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id();
-        then {
-            match_def_path(cx, fn_def_id, &paths::PTR_NULL) || match_def_path(cx, fn_def_id, &paths::PTR_NULL_MUT)
-        } else {
-            false
-        }
+    if let ExprKind::Call(pathexp, []) = expr.kind {
+        expr_path_res(cx, pathexp).opt_def_id().map_or(false, |id| {
+            match_any_def_paths(cx, id, &[&paths::PTR_NULL, &paths::PTR_NULL_MUT]).is_some()
+        })
+    } else {
+        false
     }
 }
diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs
index ea9ff37e13f..30bee213900 100644
--- a/clippy_lints/src/question_mark.rs
+++ b/clippy_lints/src/question_mark.rs
@@ -3,10 +3,10 @@ use clippy_utils::is_lang_ctor;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{eq_expr_value, match_qpath};
+use clippy_utils::{eq_expr_value, path_to_local_id};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
-use rustc_hir::LangItem::OptionNone;
+use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, MatchSource, PatKind, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -101,15 +101,14 @@ impl QuestionMark {
             if Self::is_option(cx, subject);
 
             if let PatKind::TupleStruct(path1, fields, None) = &arms[0].pat.kind;
-            if match_qpath(path1, &["Some"]);
-            if let PatKind::Binding(annot, _, bind, _) = &fields[0].kind;
+            if is_lang_ctor(cx, path1, OptionSome);
+            if let PatKind::Binding(annot, bind_id, _, _) = fields[0].kind;
             let by_ref = matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut);
 
             if let ExprKind::Block(block, None) = &arms[0].body.kind;
             if block.stmts.is_empty();
             if let Some(trailing_expr) = &block.expr;
-            if let ExprKind::Path(path) = &trailing_expr.kind;
-            if match_qpath(path, &[&bind.as_str()]);
+            if path_to_local_id(trailing_expr, bind_id);
 
             if let PatKind::Wild = arms[1].pat.kind;
             if Self::expression_returns_none(cx, arms[1].body);
diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs
index 3a6151dce71..b565c77aaec 100644
--- a/clippy_lints/src/returns.rs
+++ b/clippy_lints/src/returns.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::snippet_opt;
-use clippy_utils::{fn_def_id, in_macro, match_qpath};
+use clippy_utils::{fn_def_id, in_macro, path_to_local_id};
 use if_chain::if_chain;
 use rustc_ast::ast::Attribute;
 use rustc_errors::Applicability;
@@ -84,9 +84,8 @@ impl<'tcx> LateLintPass<'tcx> for Return {
             if local.ty.is_none();
             if cx.tcx.hir().attrs(local.hir_id).is_empty();
             if let Some(initexpr) = &local.init;
-            if let PatKind::Binding(.., ident, _) = local.pat.kind;
-            if let ExprKind::Path(qpath) = &retexpr.kind;
-            if match_qpath(qpath, &[&*ident.name.as_str()]);
+            if let PatKind::Binding(_, local_id, _, _) = local.pat.kind;
+            if path_to_local_id(retexpr, local_id);
             if !last_statement_borrows(cx, initexpr);
             if !in_external_macro(cx.sess(), initexpr.span);
             if !in_external_macro(cx.sess(), retexpr.span);
diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs
index 8cf89ae456e..191781be000 100644
--- a/clippy_lints/src/slow_vector_initialization.rs
+++ b/clippy_lints/src/slow_vector_initialization.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::sugg::Sugg;
-use clippy_utils::{get_enclosing_block, match_qpath, SpanlessEq};
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::{get_enclosing_block, is_expr_path_def_path, path_to_local, path_to_local_id, paths, SpanlessEq};
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -9,7 +10,7 @@ use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, PatKind, QPath,
 use rustc_lint::{LateContext, LateLintPass, Lint};
 use rustc_middle::hir::map::Map;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// **What it does:** Checks slow zero-filled vector initialization
@@ -46,8 +47,8 @@ declare_lint_pass!(SlowVectorInit => [SLOW_VECTOR_INITIALIZATION]);
 /// assigned to a variable. For example, `let mut vec = Vec::with_capacity(0)` or
 /// `vec = Vec::with_capacity(0)`
 struct VecAllocation<'tcx> {
-    /// Symbol of the local variable name
-    variable_name: Symbol,
+    /// HirId of the variable
+    local_id: HirId,
 
     /// Reference to the expression which allocates the vector
     allocation_expr: &'tcx Expr<'tcx>,
@@ -72,16 +73,15 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
         if_chain! {
             if let ExprKind::Assign(left, right, _) = expr.kind;
 
-            // Extract variable name
-            if let ExprKind::Path(QPath::Resolved(_, path)) = left.kind;
-            if let Some(variable_name) = path.segments.get(0);
+            // Extract variable
+            if let Some(local_id) = path_to_local(left);
 
             // Extract len argument
-            if let Some(len_arg) = Self::is_vec_with_capacity(right);
+            if let Some(len_arg) = Self::is_vec_with_capacity(cx, right);
 
             then {
                 let vi = VecAllocation {
-                    variable_name: variable_name.ident.name,
+                    local_id,
                     allocation_expr: right,
                     len_expr: len_arg,
                 };
@@ -95,13 +95,13 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
         // Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)`
         if_chain! {
             if let StmtKind::Local(local) = stmt.kind;
-            if let PatKind::Binding(BindingAnnotation::Mutable, .., variable_name, None) = local.pat.kind;
+            if let PatKind::Binding(BindingAnnotation::Mutable, local_id, _, None) = local.pat.kind;
             if let Some(init) = local.init;
-            if let Some(len_arg) = Self::is_vec_with_capacity(init);
+            if let Some(len_arg) = Self::is_vec_with_capacity(cx, init);
 
             then {
                 let vi = VecAllocation {
-                    variable_name: variable_name.name,
+                    local_id,
                     allocation_expr: init,
                     len_expr: len_arg,
                 };
@@ -115,19 +115,18 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
 impl SlowVectorInit {
     /// Checks if the given expression is `Vec::with_capacity(..)`. It will return the expression
     /// of the first argument of `with_capacity` call if it matches or `None` if it does not.
-    fn is_vec_with_capacity<'tcx>(expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
+    fn is_vec_with_capacity<'tcx>(cx: &LateContext<'_>, expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
         if_chain! {
-            if let ExprKind::Call(func, args) = expr.kind;
-            if let ExprKind::Path(ref path) = func.kind;
-            if match_qpath(path, &["Vec", "with_capacity"]);
-            if args.len() == 1;
-
+            if let ExprKind::Call(func, [arg]) = expr.kind;
+            if let ExprKind::Path(QPath::TypeRelative(ty, name)) = func.kind;
+            if name.ident.as_str() == "with_capacity";
+            if is_type_diagnostic_item(cx, cx.typeck_results().node_type(ty.hir_id), sym::vec_type);
             then {
-                return Some(&args[0]);
+                Some(arg)
+            } else {
+                None
             }
         }
-
-        None
     }
 
     /// Search initialization for the given vector
@@ -208,11 +207,9 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
     fn search_slow_extend_filling(&mut self, expr: &'tcx Expr<'_>) {
         if_chain! {
             if self.initialization_found;
-            if let ExprKind::MethodCall(path, _, args, _) = expr.kind;
-            if let ExprKind::Path(ref qpath_subj) = args[0].kind;
-            if match_qpath(qpath_subj, &[&*self.vec_alloc.variable_name.as_str()]);
+            if let ExprKind::MethodCall(path, _, [self_arg, extend_arg], _) = expr.kind;
+            if path_to_local_id(self_arg, self.vec_alloc.local_id);
             if path.ident.name == sym!(extend);
-            if let Some(extend_arg) = args.get(1);
             if self.is_repeat_take(extend_arg);
 
             then {
@@ -225,11 +222,9 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
     fn search_slow_resize_filling(&mut self, expr: &'tcx Expr<'_>) {
         if_chain! {
             if self.initialization_found;
-            if let ExprKind::MethodCall(path, _, args, _) = expr.kind;
-            if let ExprKind::Path(ref qpath_subj) = args[0].kind;
-            if match_qpath(qpath_subj, &[&*self.vec_alloc.variable_name.as_str()]);
+            if let ExprKind::MethodCall(path, _, [self_arg, len_arg, fill_arg], _) = expr.kind;
+            if path_to_local_id(self_arg, self.vec_alloc.local_id);
             if path.ident.name == sym!(resize);
-            if let (Some(len_arg), Some(fill_arg)) = (args.get(1), args.get(2));
 
             // Check that is filled with 0
             if let ExprKind::Lit(ref lit) = fill_arg.kind;
@@ -252,7 +247,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
 
             // Check that take is applied to `repeat(0)`
             if let Some(repeat_expr) = take_args.get(0);
-            if Self::is_repeat_zero(repeat_expr);
+            if self.is_repeat_zero(repeat_expr);
 
             // Check that len expression is equals to `with_capacity` expression
             if let Some(len_arg) = take_args.get(1);
@@ -267,21 +262,19 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
     }
 
     /// Returns `true` if given expression is `repeat(0)`
-    fn is_repeat_zero(expr: &Expr<'_>) -> bool {
+    fn is_repeat_zero(&self, expr: &Expr<'_>) -> bool {
         if_chain! {
-            if let ExprKind::Call(fn_expr, repeat_args) = expr.kind;
-            if let ExprKind::Path(ref qpath_repeat) = fn_expr.kind;
-            if match_qpath(qpath_repeat, &["repeat"]);
-            if let Some(repeat_arg) = repeat_args.get(0);
+            if let ExprKind::Call(fn_expr, [repeat_arg]) = expr.kind;
+            if is_expr_path_def_path(self.cx, fn_expr, &paths::ITER_REPEAT);
             if let ExprKind::Lit(ref lit) = repeat_arg.kind;
             if let LitKind::Int(0, _) = lit.node;
 
             then {
-                return true
+                true
+            } else {
+                false
             }
         }
-
-        false
     }
 }
 
diff --git a/clippy_lints/src/transmuting_null.rs b/clippy_lints/src/transmuting_null.rs
index 755132da591..888ecab1046 100644
--- a/clippy_lints/src/transmuting_null.rs
+++ b/clippy_lints/src/transmuting_null.rs
@@ -1,6 +1,6 @@
 use crate::consts::{constant_context, Constant};
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{match_def_path, paths};
+use clippy_utils::{is_expr_path_def_path, paths};
 use if_chain::if_chain;
 use rustc_ast::LitKind;
 use rustc_hir::{Expr, ExprKind};
@@ -37,18 +37,15 @@ impl<'tcx> LateLintPass<'tcx> for TransmutingNull {
         }
 
         if_chain! {
-            if let ExprKind::Call(func, args) = expr.kind;
-            if args.len() == 1;
-            if let ExprKind::Path(ref path) = func.kind;
-            if let Some(func_def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
-            if match_def_path(cx, func_def_id, &paths::TRANSMUTE);
-            then {
+            if let ExprKind::Call(func, [arg]) = expr.kind;
+            if is_expr_path_def_path(cx, func, &paths::TRANSMUTE);
 
+            then {
                 // Catching transmute over constants that resolve to `null`.
                 let mut const_eval_context = constant_context(cx, cx.typeck_results());
                 if_chain! {
-                    if let ExprKind::Path(ref _qpath) = args[0].kind;
-                    let x = const_eval_context.expr(&args[0]);
+                    if let ExprKind::Path(ref _qpath) = arg.kind;
+                    let x = const_eval_context.expr(arg);
                     if let Some(Constant::RawPtr(0)) = x;
                     then {
                         span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG)
@@ -58,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for TransmutingNull {
                 // Catching:
                 // `std::mem::transmute(0 as *const i32)`
                 if_chain! {
-                    if let ExprKind::Cast(inner_expr, _cast_ty) = args[0].kind;
+                    if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind;
                     if let ExprKind::Lit(ref lit) = inner_expr.kind;
                     if let LitKind::Int(0, _) = lit.node;
                     then {
@@ -69,10 +66,8 @@ impl<'tcx> LateLintPass<'tcx> for TransmutingNull {
                 // Catching:
                 // `std::mem::transmute(std::ptr::null::<i32>())`
                 if_chain! {
-                    if let ExprKind::Call(func1, []) = args[0].kind;
-                    if let ExprKind::Path(ref path1) = func1.kind;
-                    if let Some(func1_def_id) = cx.qpath_res(path1, func1.hir_id).opt_def_id();
-                    if match_def_path(cx, func1_def_id, &paths::PTR_NULL);
+                    if let ExprKind::Call(func1, []) = arg.kind;
+                    if is_expr_path_def_path(cx, func1, &paths::PTR_NULL);
                     then {
                         span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG)
                     }
diff --git a/clippy_lints/src/types/borrowed_box.rs b/clippy_lints/src/types/borrowed_box.rs
index 1425d8f3f37..bdeff035e5e 100644
--- a/clippy_lints/src/types/borrowed_box.rs
+++ b/clippy_lints/src/types/borrowed_box.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
-use clippy_utils::{match_path, paths};
+use clippy_utils::{match_def_path, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{
@@ -28,7 +28,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
                     _ => None,
                 });
                 then {
-                    if is_any_trait(inner) {
+                    if is_any_trait(cx, inner) {
                         // Ignore `Box<Any>` types; see issue #1884 for details.
                         return false;
                     }
@@ -84,13 +84,14 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
 }
 
 // Returns true if given type is `Any` trait.
-fn is_any_trait(t: &hir::Ty<'_>) -> bool {
+fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool {
     if_chain! {
         if let TyKind::TraitObject(traits, ..) = t.kind;
         if !traits.is_empty();
+        if let Some(trait_did) = traits[0].trait_ref.trait_def_id();
         // Only Send/Sync can be used as additional traits, so it is enough to
         // check only the first trait.
-        if match_path(traits[0].trait_ref.path, &paths::ANY_TRAIT);
+        if match_def_path(cx, trait_did, &paths::ANY_TRAIT);
         then {
             return true;
         }
diff --git a/clippy_lints/src/unnecessary_wraps.rs b/clippy_lints/src/unnecessary_wraps.rs
index d2c0f60d296..f2f1410aed7 100644
--- a/clippy_lints/src/unnecessary_wraps.rs
+++ b/clippy_lints/src/unnecessary_wraps.rs
@@ -104,14 +104,12 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
             if_chain! {
                 if !in_macro(ret_expr.span);
                 // Check if a function call.
-                if let ExprKind::Call(func, args) = ret_expr.kind;
-                // Get the Path of the function call.
-                if let ExprKind::Path(ref qpath) = func.kind;
+                if let ExprKind::Call(func, [arg]) = ret_expr.kind;
                 // Check if OPTION_SOME or RESULT_OK, depending on return type.
+                if let ExprKind::Path(qpath) = &func.kind;
                 if is_lang_ctor(cx, qpath, lang_item);
-                if args.len() == 1;
                 // Make sure the function argument does not contain a return expression.
-                if !contains_return(&args[0]);
+                if !contains_return(arg);
                 then {
                     suggs.push(
                         (
@@ -119,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
                             if inner_type.is_unit() {
                                 "".to_string()
                             } else {
-                                snippet(cx, args[0].span.source_callsite(), "..").to_string()
+                                snippet(cx, arg.span.source_callsite(), "..").to_string()
                             }
                         )
                     );
diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs
index cf8039d6059..3d3d0e19d26 100644
--- a/clippy_lints/src/utils/internal_lints.rs
+++ b/clippy_lints/src/utils/internal_lints.rs
@@ -3,7 +3,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sug
 use clippy_utils::source::snippet;
 use clippy_utils::ty::match_type;
 use clippy_utils::{
-    is_else_clause, is_expn_of, match_def_path, match_qpath, method_calls, path_to_res, paths, run_lints, SpanlessEq,
+    is_else_clause, is_expn_of, is_expr_path_def_path, match_def_path, method_calls, path_to_res, paths, run_lints,
+    SpanlessEq,
 };
 use if_chain::if_chain;
 use rustc_ast::ast::{Crate as AstCrate, ItemKind, LitKind, ModKind, NodeId};
@@ -578,8 +579,7 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls {
 
         if_chain! {
             if let ExprKind::Call(func, and_then_args) = expr.kind;
-            if let ExprKind::Path(ref path) = func.kind;
-            if match_qpath(path, &["span_lint_and_then"]);
+            if is_expr_path_def_path(cx, func, &["clippy_utils", "diagnostics", "span_lint_and_then"]);
             if and_then_args.len() == 5;
             if let ExprKind::Closure(_, _, body_id, _, _) = &and_then_args[4].kind;
             let body = cx.tcx.hir().body(*body_id);
@@ -761,8 +761,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
         if_chain! {
             // Check if this is a call to utils::match_type()
             if let ExprKind::Call(fn_path, [context, ty, ty_path]) = expr.kind;
-            if let ExprKind::Path(fn_qpath) = &fn_path.kind;
-            if match_qpath(fn_qpath, &["utils", "match_type"]);
+            if is_expr_path_def_path(cx, fn_path, &["clippy_utils", "ty", "match_type"]);
             // Extract the path to the matched type
             if let Some(segments) = path_to_matched_type(cx, ty_path);
             let segments: Vec<&str> = segments.iter().map(|sym| &**sym).collect();
@@ -771,6 +770,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
             let diag_items = cx.tcx.diagnostic_items(ty_did.krate);
             if let Some(item_name) = diag_items.iter().find_map(|(k, v)| if *v == ty_did { Some(k) } else { None });
             then {
+                // TODO: check paths constants from external crates.
                 let cx_snippet = snippet(cx, context.span, "_");
                 let ty_snippet = snippet(cx, ty.span, "_");
 
@@ -778,9 +778,9 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
                     cx,
                     MATCH_TYPE_ON_DIAGNOSTIC_ITEM,
                     expr.span,
-                    "usage of `utils::match_type()` on a type diagnostic item",
+                    "usage of `clippy_utils::ty::match_type()` on a type diagnostic item",
                     "try",
-                    format!("utils::is_type_diagnostic_item({}, {}, sym::{})", cx_snippet, ty_snippet, item_name),
+                    format!("clippy_utils::ty::is_type_diagnostic_item({}, {}, sym::{})", cx_snippet, ty_snippet, item_name),
                     Applicability::MaybeIncorrect,
                 );
             }
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 8e1a2105b96..4a523520a43 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -397,6 +397,29 @@ pub fn match_qpath(path: &QPath<'_>, segments: &[&str]) -> bool {
     }
 }
 
+/// If the expression is a path, resolve it. Otherwise, return `Res::Err`.
+pub fn expr_path_res(cx: &LateContext<'_>, expr: &Expr<'_>) -> Res {
+    if let ExprKind::Path(p) = &expr.kind {
+        cx.qpath_res(p, expr.hir_id)
+    } else {
+        Res::Err
+    }
+}
+
+/// Resolves the path to a `DefId` and checks if it matches the given path.
+pub fn is_qpath_def_path(cx: &LateContext<'_>, path: &QPath<'_>, hir_id: HirId, segments: &[&str]) -> bool {
+    cx.qpath_res(path, hir_id)
+        .opt_def_id()
+        .map_or(false, |id| match_def_path(cx, id, segments))
+}
+
+/// If the expression is a path, resolves it to a `DefId` and checks if it matches the given path.
+pub fn is_expr_path_def_path(cx: &LateContext<'_>, expr: &Expr<'_>, segments: &[&str]) -> bool {
+    expr_path_res(cx, expr)
+        .opt_def_id()
+        .map_or(false, |id| match_def_path(cx, id, segments))
+}
+
 /// THIS METHOD IS DEPRECATED and will eventually be removed since it does not match against the
 /// entire path or resolved `DefId`. Prefer using `match_def_path`. Consider getting a `DefId` from
 /// `QPath::Resolved.1.res.opt_def_id()`.
@@ -425,20 +448,6 @@ pub fn match_path(path: &Path<'_>, segments: &[&str]) -> bool {
         .all(|(a, b)| a.ident.name.as_str() == *b)
 }
 
-/// Matches a `Path` against a slice of segment string literals, e.g.
-///
-/// # Examples
-/// ```rust,ignore
-/// match_path_ast(path, &["std", "rt", "begin_unwind"])
-/// ```
-pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
-    path.segments
-        .iter()
-        .rev()
-        .zip(segments.iter().rev())
-        .all(|(a, b)| a.ident.name.as_str() == *b)
-}
-
 /// If the expression is a path to a local, returns the canonical `HirId` of the local.
 pub fn path_to_local(expr: &Expr<'_>) -> Option<HirId> {
     if let ExprKind::Path(QPath::Resolved(None, ref path)) = expr.kind {
@@ -1148,29 +1157,47 @@ pub fn match_function_call<'tcx>(
     None
 }
 
+/// Checks if the given `DefId` matches any of the paths. Returns the index of matching path, if
+/// any.
+pub fn match_any_def_paths(cx: &LateContext<'_>, did: DefId, paths: &[&[&str]]) -> Option<usize> {
+    let search_path = cx.get_def_path(did);
+    paths
+        .iter()
+        .position(|p| p.iter().map(|x| Symbol::intern(x)).eq(search_path.iter().cloned()))
+}
+
+/// Checks if the given `DefId` matches the path.
 pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) -> bool {
-    // We have to convert `syms` to `&[Symbol]` here because rustc's `match_def_path`
-    // accepts only that. We should probably move to Symbols in Clippy as well.
-    let syms = syms.iter().map(|p| Symbol::intern(p)).collect::<Vec<Symbol>>();
-    cx.match_def_path(did, &syms)
+    // We should probably move to Symbols in Clippy as well rather than interning every time.
+    let path = cx.get_def_path(did);
+    syms.iter().map(|x| Symbol::intern(x)).eq(path.iter().cloned())
 }
 
-pub fn match_panic_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx [Expr<'tcx>]> {
-    match_function_call(cx, expr, &paths::BEGIN_PANIC)
-        .or_else(|| match_function_call(cx, expr, &paths::BEGIN_PANIC_FMT))
-        .or_else(|| match_function_call(cx, expr, &paths::PANIC_ANY))
-        .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC))
-        .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_FMT))
-        .or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_STR))
+pub fn match_panic_call(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
+    if let ExprKind::Call(func, [arg]) = expr.kind {
+        expr_path_res(cx, func)
+            .opt_def_id()
+            .map_or(false, |id| match_panic_def_id(cx, id))
+            .then(|| arg)
+    } else {
+        None
+    }
 }
 
 pub fn match_panic_def_id(cx: &LateContext<'_>, did: DefId) -> bool {
-    match_def_path(cx, did, &paths::BEGIN_PANIC)
-        || match_def_path(cx, did, &paths::BEGIN_PANIC_FMT)
-        || match_def_path(cx, did, &paths::PANIC_ANY)
-        || match_def_path(cx, did, &paths::PANICKING_PANIC)
-        || match_def_path(cx, did, &paths::PANICKING_PANIC_FMT)
-        || match_def_path(cx, did, &paths::PANICKING_PANIC_STR)
+    match_any_def_paths(
+        cx,
+        did,
+        &[
+            &paths::BEGIN_PANIC,
+            &paths::BEGIN_PANIC_FMT,
+            &paths::PANIC_ANY,
+            &paths::PANICKING_PANIC,
+            &paths::PANICKING_PANIC_FMT,
+            &paths::PANICKING_PANIC_STR,
+        ],
+    )
+    .is_some()
 }
 
 /// Returns the list of condition expressions and the list of blocks in a
diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs
index ed8915f59e1..21011dbded6 100644
--- a/clippy_utils/src/paths.rs
+++ b/clippy_utils/src/paths.rs
@@ -4,7 +4,7 @@
 //! Whenever possible, please consider diagnostic items over hardcoded paths.
 //! See <https://github.com/rust-lang/rust-clippy/issues/5393> for more information.
 
-pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"];
+pub const ANY_TRAIT: [&str; 3] = ["core", "any", "Any"];
 pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
 pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
 pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
@@ -42,6 +42,8 @@ pub const FMT_ARGUMENTS_NEW_V1_FORMATTED: [&str; 4] = ["core", "fmt", "Arguments
 pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"];
 pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
 pub const FROM_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "FromIterator"];
+pub const FROM_ITERATOR_METHOD: [&str; 6] = ["core", "iter", "traits", "collect", "FromIterator", "from_iter"];
+pub const FROM_STR_METHOD: [&str; 5] = ["core", "str", "traits", "FromStr", "from_str"];
 pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
 pub const HASH: [&str; 3] = ["core", "hash", "Hash"];
 pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"];
@@ -58,8 +60,9 @@ pub const INTO: [&str; 3] = ["core", "convert", "Into"];
 pub const INTO_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "IntoIterator"];
 pub const IO_READ: [&str; 3] = ["std", "io", "Read"];
 pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
-pub const IPADDR_V4: [&str; 4] = ["std", "net", "IpAddr", "V4"];
-pub const IPADDR_V6: [&str; 4] = ["std", "net", "IpAddr", "V6"];
+pub const IPADDR_V4: [&str; 5] = ["std", "net", "ip", "IpAddr", "V4"];
+pub const IPADDR_V6: [&str; 5] = ["std", "net", "ip", "IpAddr", "V6"];
+pub const ITER_REPEAT: [&str; 5] = ["core", "iter", "sources", "repeat", "repeat"];
 #[cfg(feature = "internal-lints")]
 pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
 #[cfg(feature = "internal-lints")]
@@ -126,7 +129,6 @@ pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"];
 pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"];
 pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"];
 pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"];
-pub const REPEAT: [&str; 3] = ["core", "iter", "repeat"];
 pub const RESULT: [&str; 3] = ["core", "result", "Result"];
 pub const RESULT_ERR: [&str; 4] = ["core", "result", "Result", "Err"];
 pub const RESULT_OK: [&str; 4] = ["core", "result", "Result", "Ok"];
@@ -140,7 +142,7 @@ pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec
 pub const SLICE_ITER: [&str; 4] = ["core", "slice", "iter", "Iter"];
 pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];
 pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
-pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"];
+pub const CONVERT_IDENTITY: [&str; 3] = ["core", "convert", "identity"];
 pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"];
 pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
 pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
diff --git a/doc/adding_lints.md b/doc/adding_lints.md
index 99b86953d51..50f0d724016 100644
--- a/doc/adding_lints.md
+++ b/doc/adding_lints.md
@@ -625,7 +625,7 @@ in the following steps:
 Here are some pointers to things you are likely going to need for every lint:
 
 * [Clippy utils][utils] - Various helper functions. Maybe the function you need
-  is already in here (`implements_trait`, `match_path`, `snippet`, etc)
+  is already in here (`implements_trait`, `match_def_path`, `snippet`, etc)
 * [Clippy diagnostics][diagnostics]
 * [The `if_chain` macro][if_chain]
 * [`from_expansion`][from_expansion] and [`in_external_macro`][in_external_macro]
diff --git a/tests/ui-internal/collapsible_span_lint_calls.fixed b/tests/ui-internal/collapsible_span_lint_calls.fixed
index e588c23345e..7764cc8da78 100644
--- a/tests/ui-internal/collapsible_span_lint_calls.fixed
+++ b/tests/ui-internal/collapsible_span_lint_calls.fixed
@@ -2,58 +2,18 @@
 #![deny(clippy::internal)]
 #![feature(rustc_private)]
 
+extern crate clippy_utils;
 extern crate rustc_ast;
 extern crate rustc_errors;
 extern crate rustc_lint;
 extern crate rustc_session;
 extern crate rustc_span;
 
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
 use rustc_ast::ast::Expr;
-use rustc_errors::{Applicability, DiagnosticBuilder};
-use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
+use rustc_errors::Applicability;
+use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Span;
-
-#[allow(unused_variables)]
-pub fn span_lint_and_then<'a, T: LintContext, F>(cx: &'a T, lint: &'static Lint, sp: Span, msg: &str, f: F)
-where
-    F: for<'b> FnOnce(&mut DiagnosticBuilder<'b>),
-{
-}
-
-#[allow(unused_variables)]
-fn span_lint_and_help<'a, T: LintContext>(
-    cx: &'a T,
-    lint: &'static Lint,
-    span: Span,
-    msg: &str,
-    option_span: Option<Span>,
-    help: &str,
-) {
-}
-
-#[allow(unused_variables)]
-fn span_lint_and_note<'a, T: LintContext>(
-    cx: &'a T,
-    lint: &'static Lint,
-    span: Span,
-    msg: &str,
-    note_span: Option<Span>,
-    note: &str,
-) {
-}
-
-#[allow(unused_variables)]
-fn span_lint_and_sugg<'a, T: LintContext>(
-    cx: &'a T,
-    lint: &'static Lint,
-    sp: Span,
-    msg: &str,
-    help: &str,
-    sugg: String,
-    applicability: Applicability,
-) {
-}
 
 declare_tool_lint! {
     pub clippy::TEST_LINT,
diff --git a/tests/ui-internal/collapsible_span_lint_calls.rs b/tests/ui-internal/collapsible_span_lint_calls.rs
index d5dd3bb562b..bdd296db832 100644
--- a/tests/ui-internal/collapsible_span_lint_calls.rs
+++ b/tests/ui-internal/collapsible_span_lint_calls.rs
@@ -2,58 +2,18 @@
 #![deny(clippy::internal)]
 #![feature(rustc_private)]
 
+extern crate clippy_utils;
 extern crate rustc_ast;
 extern crate rustc_errors;
 extern crate rustc_lint;
 extern crate rustc_session;
 extern crate rustc_span;
 
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
 use rustc_ast::ast::Expr;
-use rustc_errors::{Applicability, DiagnosticBuilder};
-use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
+use rustc_errors::Applicability;
+use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Span;
-
-#[allow(unused_variables)]
-pub fn span_lint_and_then<'a, T: LintContext, F>(cx: &'a T, lint: &'static Lint, sp: Span, msg: &str, f: F)
-where
-    F: for<'b> FnOnce(&mut DiagnosticBuilder<'b>),
-{
-}
-
-#[allow(unused_variables)]
-fn span_lint_and_help<'a, T: LintContext>(
-    cx: &'a T,
-    lint: &'static Lint,
-    span: Span,
-    msg: &str,
-    option_span: Option<Span>,
-    help: &str,
-) {
-}
-
-#[allow(unused_variables)]
-fn span_lint_and_note<'a, T: LintContext>(
-    cx: &'a T,
-    lint: &'static Lint,
-    span: Span,
-    msg: &str,
-    note_span: Option<Span>,
-    note: &str,
-) {
-}
-
-#[allow(unused_variables)]
-fn span_lint_and_sugg<'a, T: LintContext>(
-    cx: &'a T,
-    lint: &'static Lint,
-    sp: Span,
-    msg: &str,
-    help: &str,
-    sugg: String,
-    applicability: Applicability,
-) {
-}
 
 declare_tool_lint! {
     pub clippy::TEST_LINT,
diff --git a/tests/ui-internal/collapsible_span_lint_calls.stderr b/tests/ui-internal/collapsible_span_lint_calls.stderr
index 874d4a9f255..0632b038577 100644
--- a/tests/ui-internal/collapsible_span_lint_calls.stderr
+++ b/tests/ui-internal/collapsible_span_lint_calls.stderr
@@ -1,5 +1,5 @@
 error: this call is collapsible
-  --> $DIR/collapsible_span_lint_calls.rs:75:9
+  --> $DIR/collapsible_span_lint_calls.rs:35:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
 LL | |             db.span_suggestion(expr.span, help_msg, sugg.to_string(), Applicability::MachineApplicable);
@@ -14,7 +14,7 @@ LL | #![deny(clippy::internal)]
    = note: `#[deny(clippy::collapsible_span_lint_calls)]` implied by `#[deny(clippy::internal)]`
 
 error: this call is collapsible
-  --> $DIR/collapsible_span_lint_calls.rs:78:9
+  --> $DIR/collapsible_span_lint_calls.rs:38:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
 LL | |             db.span_help(expr.span, help_msg);
@@ -22,7 +22,7 @@ LL | |         });
    | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), help_msg)`
 
 error: this call is collapsible
-  --> $DIR/collapsible_span_lint_calls.rs:81:9
+  --> $DIR/collapsible_span_lint_calls.rs:41:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
 LL | |             db.help(help_msg);
@@ -30,7 +30,7 @@ LL | |         });
    | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg)`
 
 error: this call is collspible
-  --> $DIR/collapsible_span_lint_calls.rs:84:9
+  --> $DIR/collapsible_span_lint_calls.rs:44:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
 LL | |             db.span_note(expr.span, note_msg);
@@ -38,7 +38,7 @@ LL | |         });
    | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg)`
 
 error: this call is collspible
-  --> $DIR/collapsible_span_lint_calls.rs:87:9
+  --> $DIR/collapsible_span_lint_calls.rs:47:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
 LL | |             db.note(note_msg);
diff --git a/tests/ui-internal/match_type_on_diag_item.rs b/tests/ui-internal/match_type_on_diag_item.rs
index fe950b0aa7c..063f0c6460c 100644
--- a/tests/ui-internal/match_type_on_diag_item.rs
+++ b/tests/ui-internal/match_type_on_diag_item.rs
@@ -1,29 +1,18 @@
 #![deny(clippy::internal)]
 #![feature(rustc_private)]
 
+extern crate clippy_utils;
 extern crate rustc_hir;
 extern crate rustc_lint;
 extern crate rustc_middle;
+
 #[macro_use]
 extern crate rustc_session;
+use clippy_utils::{paths, ty::match_type};
 use rustc_hir::Expr;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty;
 
-mod paths {
-    pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
-}
-
-mod utils {
-    use super::*;
-
-    pub fn match_type(_cx: &LateContext<'_>, _ty: Ty<'_>, _path: &[&str]) -> bool {
-        false
-    }
-}
-
-use utils::match_type;
-
 declare_lint! {
     pub TEST_LINT,
     Warn,
@@ -38,12 +27,12 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr) {
         let ty = cx.typeck_results().expr_ty(expr);
 
-        let _ = match_type(cx, ty, &paths::VEC);
+        let _ = match_type(cx, ty, &paths::VEC); // FIXME: Doesn't lint external paths
         let _ = match_type(cx, ty, &OPTION);
         let _ = match_type(cx, ty, &["core", "result", "Result"]);
 
         let rc_path = &["alloc", "rc", "Rc"];
-        let _ = utils::match_type(cx, ty, rc_path);
+        let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
     }
 }
 
diff --git a/tests/ui-internal/match_type_on_diag_item.stderr b/tests/ui-internal/match_type_on_diag_item.stderr
index 82465dbaf6e..71472960565 100644
--- a/tests/ui-internal/match_type_on_diag_item.stderr
+++ b/tests/ui-internal/match_type_on_diag_item.stderr
@@ -1,8 +1,8 @@
-error: usage of `utils::match_type()` on a type diagnostic item
-  --> $DIR/match_type_on_diag_item.rs:41:17
+error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
+  --> $DIR/match_type_on_diag_item.rs:31:17
    |
-LL |         let _ = match_type(cx, ty, &paths::VEC);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym::vec_type)`
+LL |         let _ = match_type(cx, ty, &OPTION);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::option_type)`
    |
 note: the lint level is defined here
   --> $DIR/match_type_on_diag_item.rs:1:9
@@ -11,23 +11,17 @@ LL | #![deny(clippy::internal)]
    |         ^^^^^^^^^^^^^^^^
    = note: `#[deny(clippy::match_type_on_diagnostic_item)]` implied by `#[deny(clippy::internal)]`
 
-error: usage of `utils::match_type()` on a type diagnostic item
-  --> $DIR/match_type_on_diag_item.rs:42:17
-   |
-LL |         let _ = match_type(cx, ty, &OPTION);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym::option_type)`
-
-error: usage of `utils::match_type()` on a type diagnostic item
-  --> $DIR/match_type_on_diag_item.rs:43:17
+error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
+  --> $DIR/match_type_on_diag_item.rs:32:17
    |
 LL |         let _ = match_type(cx, ty, &["core", "result", "Result"]);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym::result_type)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::result_type)`
 
-error: usage of `utils::match_type()` on a type diagnostic item
-  --> $DIR/match_type_on_diag_item.rs:46:17
+error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
+  --> $DIR/match_type_on_diag_item.rs:35:17
    |
-LL |         let _ = utils::match_type(cx, ty, rc_path);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym::Rc)`
+LL |         let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Rc)`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/repl_uninit.rs b/tests/ui/repl_uninit.rs
index ad5b8e4857d..6c7e2b854dc 100644
--- a/tests/ui/repl_uninit.rs
+++ b/tests/ui/repl_uninit.rs
@@ -1,5 +1,5 @@
-#![allow(deprecated, invalid_value)]
-#![warn(clippy::all)]
+#![allow(deprecated, invalid_value, clippy::uninit_assumed_init)]
+#![warn(clippy::mem_replace_with_uninit)]
 
 use std::mem;
 
diff --git a/tests/ui/uninit.rs b/tests/ui/uninit.rs
index f42b884e0f0..1ed3883c1f0 100644
--- a/tests/ui/uninit.rs
+++ b/tests/ui/uninit.rs
@@ -1,6 +1,6 @@
 #![feature(stmt_expr_attributes)]
 
-use std::mem::MaybeUninit;
+use std::mem::{self, MaybeUninit};
 
 fn main() {
     let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
@@ -19,4 +19,7 @@ fn main() {
 
     // This is OK, because all constitutent types are uninit-compatible.
     let _: (MaybeUninit<usize>, [MaybeUninit<bool>; 2]) = unsafe { MaybeUninit::uninit().assume_init() };
+
+    // Was a false negative.
+    let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() };
 }
diff --git a/tests/ui/uninit.stderr b/tests/ui/uninit.stderr
index a37233ecdda..85b64a8419a 100644
--- a/tests/ui/uninit.stderr
+++ b/tests/ui/uninit.stderr
@@ -12,5 +12,11 @@ error: this call for this type may be undefined behavior
 LL |     let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: this call for this type may be undefined behavior
+  --> $DIR/uninit.rs:24:29
+   |
+LL |     let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() };
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors