diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs
index 7c9df141d666..f16d10fde929 100644
--- a/clippy_lints/src/booleans.rs
+++ b/clippy_lints/src/booleans.rs
@@ -1,5 +1,5 @@
 use crate::utils::{
-    get_trait_def_id, implements_trait, in_macro, match_type, paths, snippet_opt, span_lint_and_sugg,
+    get_trait_def_id, implements_trait, in_macro, is_type_diagnostic_item, paths, snippet_opt, span_lint_and_sugg,
     span_lint_and_then, SpanlessEq,
 };
 use if_chain::if_chain;
@@ -249,7 +249,9 @@ fn simplify_not(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> Option<String> {
         },
         ExprKind::MethodCall(path, _, args) if args.len() == 1 => {
             let type_of_receiver = cx.tables.expr_ty(&args[0]);
-            if !match_type(cx, type_of_receiver, &paths::OPTION) && !match_type(cx, type_of_receiver, &paths::RESULT) {
+            if !is_type_diagnostic_item(cx, type_of_receiver, sym!(option_type))
+                && !is_type_diagnostic_item(cx, type_of_receiver, sym!(result_type))
+            {
                 return None;
             }
             METHODS_WITH_NEGATION
diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs
index 98abc801302e..93a394b79e55 100644
--- a/clippy_lints/src/cognitive_complexity.rs
+++ b/clippy_lints/src/cognitive_complexity.rs
@@ -9,7 +9,7 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
 use rustc_span::BytePos;
 
-use crate::utils::{match_type, paths, snippet_opt, span_lint_and_help, LimitStack};
+use crate::utils::{is_type_diagnostic_item, snippet_opt, span_lint_and_help, LimitStack};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for methods with high cognitive complexity.
@@ -61,7 +61,7 @@ impl CognitiveComplexity {
         helper.visit_expr(expr);
         let CCHelper { cc, returns } = helper;
         let ret_ty = cx.tables.node_type(expr.hir_id);
-        let ret_adjust = if match_type(cx, ret_ty, &paths::RESULT) {
+        let ret_adjust = if is_type_diagnostic_item(cx, ret_ty, sym!(result_type)) {
             returns
         } else {
             #[allow(clippy::integer_division)]
diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs
index 12c9ba8dcd20..926bd8ed001f 100644
--- a/clippy_lints/src/doc.rs
+++ b/clippy_lints/src/doc.rs
@@ -1,4 +1,4 @@
-use crate::utils::{implements_trait, is_entrypoint_fn, match_type, paths, return_ty, span_lint};
+use crate::utils::{implements_trait, is_entrypoint_fn, is_type_diagnostic_item, return_ty, span_lint};
 use if_chain::if_chain;
 use itertools::Itertools;
 use rustc_ast::ast::{AttrKind, Attribute};
@@ -217,7 +217,7 @@ fn lint_for_missing_headers<'a, 'tcx>(
         );
     }
     if !headers.errors {
-        if match_type(cx, return_ty(cx, hir_id), &paths::RESULT) {
+        if is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym!(result_type)) {
             span_lint(
                 cx,
                 MISSING_ERRORS_DOC,
@@ -235,7 +235,7 @@ fn lint_for_missing_headers<'a, 'tcx>(
                 if let ty::Opaque(_, subs) = ret_ty.kind;
                 if let Some(gen) = subs.types().next();
                 if let ty::Generator(_, subs, _) = gen.kind;
-                if match_type(cx, subs.as_generator().return_ty(), &paths::RESULT);
+                if is_type_diagnostic_item(cx, subs.as_generator().return_ty(), sym!(result_type));
                 then {
                     span_lint(
                         cx,
diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs
index d44481dd24a4..8e45a09b489e 100644
--- a/clippy_lints/src/fallible_impl_from.rs
+++ b/clippy_lints/src/fallible_impl_from.rs
@@ -1,10 +1,12 @@
-use crate::utils::paths::{BEGIN_PANIC, BEGIN_PANIC_FMT, FROM_TRAIT, OPTION, RESULT};
-use crate::utils::{is_expn_of, match_def_path, method_chain_args, span_lint_and_then, walk_ptrs_ty};
+use crate::utils::paths::{BEGIN_PANIC, BEGIN_PANIC_FMT, FROM_TRAIT};
+use crate::utils::{
+    is_expn_of, is_type_diagnostic_item, match_def_path, method_chain_args, span_lint_and_then, walk_ptrs_ty,
+};
 use if_chain::if_chain;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::map::Map;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::Span;
 
@@ -76,7 +78,9 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
             // check for `unwrap`
             if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
                 let reciever_ty = walk_ptrs_ty(self.tables.expr_ty(&arglists[0][0]));
-                if match_type(self.lcx, reciever_ty, &OPTION) || match_type(self.lcx, reciever_ty, &RESULT) {
+                if is_type_diagnostic_item(self.lcx, reciever_ty, sym!(option_type))
+                    || is_type_diagnostic_item(self.lcx, reciever_ty, sym!(result_type))
+                {
                     self.result.push(expr.span);
                 }
             }
@@ -124,10 +128,3 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
         }
     }
 }
-
-fn match_type(cx: &LateContext<'_, '_>, ty: Ty<'_>, path: &[&str]) -> bool {
-    match ty.kind {
-        ty::Adt(adt, _) => match_def_path(cx, adt.did, path),
-        _ => false,
-    }
-}
diff --git a/clippy_lints/src/if_let_some_result.rs b/clippy_lints/src/if_let_some_result.rs
index 248337054225..9b13f7609247 100644
--- a/clippy_lints/src/if_let_some_result.rs
+++ b/clippy_lints/src/if_let_some_result.rs
@@ -1,4 +1,4 @@
-use crate::utils::{match_type, method_chain_args, paths, snippet_with_applicability, span_lint_and_sugg};
+use crate::utils::{is_type_diagnostic_item, method_chain_args, snippet_with_applicability, span_lint_and_sugg};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, MatchSource, PatKind, QPath};
@@ -45,8 +45,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OkIfLet {
             if let ExprKind::MethodCall(_, ok_span, ref result_types) = op.kind; //check is expr.ok() has type Result<T,E>.ok()
             if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _)  = body[0].pat.kind; //get operation
             if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized;
-            let is_result_type = match_type(cx, cx.tables.expr_ty(&result_types[0]), &paths::RESULT);
-            if rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(x, false)) == "Some" && is_result_type;
+            if is_type_diagnostic_item(cx, cx.tables.expr_ty(&result_types[0]), sym!(result_type));
+            if rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(x, false)) == "Some";
 
             then {
                 let mut applicability = Applicability::MachineApplicable;
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index 8e1501956dd0..6a4f86d7f015 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -1392,7 +1392,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>, e
 /// Checks for `for` loops over `Option`s and `Result`s.
 fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>) {
     let ty = cx.tables.expr_ty(arg);
-    if match_type(cx, ty, &paths::OPTION) {
+    if is_type_diagnostic_item(cx, ty, sym!(option_type)) {
         span_lint_and_help(
             cx,
             FOR_LOOP_OVER_OPTION,
@@ -1408,7 +1408,7 @@ fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat<'_>, arg: &Expr<'_>) {
                 snippet(cx, arg.span, "_")
             ),
         );
-    } else if match_type(cx, ty, &paths::RESULT) {
+    } else if is_type_diagnostic_item(cx, ty, sym!(result_type)) {
         span_lint_and_help(
             cx,
             FOR_LOOP_OVER_RESULT,
diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs
index 58c94d7208d1..5c5cf8015f40 100644
--- a/clippy_lints/src/map_clone.rs
+++ b/clippy_lints/src/map_clone.rs
@@ -1,6 +1,6 @@
 use crate::utils::paths;
 use crate::utils::{
-    is_copy, match_trait_method, match_type, remove_blocks, snippet_with_applicability, span_lint_and_sugg,
+    is_copy, is_type_diagnostic_item, match_trait_method, remove_blocks, snippet_with_applicability, span_lint_and_sugg,
 };
 use if_chain::if_chain;
 use rustc_ast::ast::Ident;
@@ -52,7 +52,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MapClone {
             if args.len() == 2;
             if method.ident.as_str() == "map";
             let ty = cx.tables.expr_ty(&args[0]);
-            if match_type(cx, ty, &paths::OPTION) || match_trait_method(cx, e, &paths::ITERATOR);
+            if is_type_diagnostic_item(cx, ty, sym!(option_type)) || match_trait_method(cx, e, &paths::ITERATOR);
             if let hir::ExprKind::Closure(_, _, body_id, _, _) = args[1].kind;
             let closure_body = cx.tcx.hir().body(body_id);
             let closure_expr = remove_blocks(&closure_body.value);
diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs
index c5bb559e18ea..ba10319ff461 100644
--- a/clippy_lints/src/map_unit_fn.rs
+++ b/clippy_lints/src/map_unit_fn.rs
@@ -1,5 +1,4 @@
-use crate::utils::paths;
-use crate::utils::{iter_input_pats, match_type, method_chain_args, snippet, span_lint_and_then};
+use crate::utils::{is_type_diagnostic_item, iter_input_pats, method_chain_args, snippet, span_lint_and_then};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -206,9 +205,9 @@ fn suggestion_msg(function_type: &str, map_type: &str) -> String {
 fn lint_map_unit_fn(cx: &LateContext<'_, '_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr<'_>, map_args: &[hir::Expr<'_>]) {
     let var_arg = &map_args[0];
 
-    let (map_type, variant, lint) = if match_type(cx, cx.tables.expr_ty(var_arg), &paths::OPTION) {
+    let (map_type, variant, lint) = if is_type_diagnostic_item(cx, cx.tables.expr_ty(var_arg), sym!(option_type)) {
         ("Option", "Some", OPTION_MAP_UNIT_FN)
-    } else if match_type(cx, cx.tables.expr_ty(var_arg), &paths::RESULT) {
+    } else if is_type_diagnostic_item(cx, cx.tables.expr_ty(var_arg), sym!(result_type)) {
         ("Result", "Ok", RESULT_MAP_UNIT_FN)
     } else {
         return;
diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs
index 4298e62b8037..206a842d21ca 100644
--- a/clippy_lints/src/matches.rs
+++ b/clippy_lints/src/matches.rs
@@ -3,10 +3,10 @@ use crate::utils::paths;
 use crate::utils::sugg::Sugg;
 use crate::utils::usage::is_unused;
 use crate::utils::{
-    expr_block, get_arg_name, get_parent_expr, in_macro, indent_of, is_allowed, is_expn_of, is_refutable, is_wild,
-    match_qpath, match_type, match_var, multispan_sugg, remove_blocks, snippet, snippet_block,
-    snippet_with_applicability, span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then,
-    walk_ptrs_ty,
+    expr_block, get_arg_name, get_parent_expr, in_macro, indent_of, is_allowed, is_expn_of, is_refutable,
+    is_type_diagnostic_item, is_wild, match_qpath, match_type, match_var, multispan_sugg, remove_blocks, snippet,
+    snippet_block, snippet_with_applicability, span_lint_and_help, span_lint_and_note, span_lint_and_sugg,
+    span_lint_and_then, walk_ptrs_ty,
 };
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
@@ -642,7 +642,7 @@ fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<'
 
 fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
     let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex));
-    if match_type(cx, ex_ty, &paths::RESULT) {
+    if is_type_diagnostic_item(cx, ex_ty, sym!(result_type)) {
         for arm in arms {
             if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pat.kind {
                 let path_str = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_qpath(path, false));
diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs
index 35b8842dc450..0bd4c4805b34 100644
--- a/clippy_lints/src/mem_replace.rs
+++ b/clippy_lints/src/mem_replace.rs
@@ -9,6 +9,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::Span;
+use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// **What it does:** Checks for `mem::replace()` on an `Option` with
@@ -141,7 +142,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, expr_span
             if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind;
             if let Some(repl_def_id) = cx.tables.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id();
             then {
-                if match_def_path(cx, repl_def_id, &paths::MEM_UNINITIALIZED) {
+                if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) {
                     span_lint_and_help(
                         cx,
                         MEM_REPLACE_WITH_UNINIT,
@@ -149,7 +150,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_, '_>, src: &Expr<'_>, expr_span
                         "replacing with `mem::uninitialized()`",
                         "consider using the `take_mut` crate instead",
                     );
-                } else if match_def_path(cx, repl_def_id, &paths::MEM_ZEROED) &&
+                } else if cx.tcx.is_diagnostic_item(sym::mem_zeroed, repl_def_id) &&
                         !cx.tables.expr_ty(src).is_primitive() {
                     span_lint_and_help(
                         cx,
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 19ed50c42e35..3a0e4decec25 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -1836,9 +1836,9 @@ fn lint_expect_fun_call(
     }
 
     let receiver_type = cx.tables.expr_ty_adjusted(&args[0]);
-    let closure_args = if match_type(cx, receiver_type, &paths::OPTION) {
+    let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym!(option_type)) {
         "||"
-    } else if match_type(cx, receiver_type, &paths::RESULT) {
+    } else if is_type_diagnostic_item(cx, receiver_type, sym!(result_type)) {
         "|_|"
     } else {
         return;
@@ -1998,9 +1998,9 @@ fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, arg: &h
     let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(arg));
 
     if let ty::Adt(_, subst) = obj_ty.kind {
-        let caller_type = if match_type(cx, obj_ty, &paths::RC) {
+        let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
             "Rc"
-        } else if match_type(cx, obj_ty, &paths::ARC) {
+        } else if is_type_diagnostic_item(cx, obj_ty, sym::Arc) {
             "Arc"
         } else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
             "Weak"
@@ -2067,7 +2067,7 @@ fn lint_cstring_as_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, source: &
     if_chain! {
         let source_type = cx.tables.expr_ty(source);
         if let ty::Adt(def, substs) = source_type.kind;
-        if match_def_path(cx, def.did, &paths::RESULT);
+        if cx.tcx.is_diagnostic_item(sym!(result_type), def.did);
         if match_type(cx, substs.type_at(0), &paths::CSTRING);
         then {
             span_lint_and_then(
@@ -2395,9 +2395,9 @@ fn derefs_to_slice<'a, 'tcx>(
 fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::Expr<'_>]) {
     let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&unwrap_args[0]));
 
-    let mess = if match_type(cx, obj_ty, &paths::OPTION) {
+    let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) {
         Some((OPTION_UNWRAP_USED, "an Option", "None"))
-    } else if match_type(cx, obj_ty, &paths::RESULT) {
+    } else if is_type_diagnostic_item(cx, obj_ty, sym!(result_type)) {
         Some((RESULT_UNWRAP_USED, "a Result", "Err"))
     } else {
         None
@@ -2422,9 +2422,9 @@ fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hi
 fn lint_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) {
     let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(&expect_args[0]));
 
-    let mess = if match_type(cx, obj_ty, &paths::OPTION) {
+    let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) {
         Some((OPTION_EXPECT_USED, "an Option", "None"))
-    } else if match_type(cx, obj_ty, &paths::RESULT) {
+    } else if is_type_diagnostic_item(cx, obj_ty, sym!(result_type)) {
         Some((RESULT_EXPECT_USED, "a Result", "Err"))
     } else {
         None
@@ -2445,7 +2445,7 @@ fn lint_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, expect_args: &[hi
 fn lint_ok_expect(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, ok_args: &[hir::Expr<'_>]) {
     if_chain! {
         // lint if the caller of `ok()` is a `Result`
-        if match_type(cx, cx.tables.expr_ty(&ok_args[0]), &paths::RESULT);
+        if is_type_diagnostic_item(cx, cx.tables.expr_ty(&ok_args[0]), sym!(result_type));
         let result_type = cx.tables.expr_ty(&ok_args[0]);
         if let Some(error_type) = get_error_type(cx, result_type);
         if has_debug_impl(error_type, cx);
@@ -2491,8 +2491,8 @@ fn lint_map_unwrap_or_else<'a, 'tcx>(
     unwrap_args: &'tcx [hir::Expr<'_>],
 ) {
     // lint if the caller of `map()` is an `Option`
-    let is_option = match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION);
-    let is_result = match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::RESULT);
+    let is_option = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(option_type));
+    let is_result = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(result_type));
 
     if is_option || is_result {
         // Don't make a suggestion that may fail to compile due to mutably borrowing
@@ -2559,8 +2559,8 @@ fn lint_map_or_none<'a, 'tcx>(
     expr: &'tcx hir::Expr<'_>,
     map_or_args: &'tcx [hir::Expr<'_>],
 ) {
-    let is_option = match_type(cx, cx.tables.expr_ty(&map_or_args[0]), &paths::OPTION);
-    let is_result = match_type(cx, cx.tables.expr_ty(&map_or_args[0]), &paths::RESULT);
+    let is_option = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_or_args[0]), sym!(option_type));
+    let is_result = is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_or_args[0]), sym!(result_type));
 
     // There are two variants of this `map_or` lint:
     // (1) using `map_or` as an adapter from `Result<T,E>` to `Option<T>`
@@ -3209,10 +3209,7 @@ fn is_maybe_uninit_ty_valid(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool {
     match ty.kind {
         ty::Array(ref component, _) => is_maybe_uninit_ty_valid(cx, component),
         ty::Tuple(ref types) => types.types().all(|ty| is_maybe_uninit_ty_valid(cx, ty)),
-        ty::Adt(ref adt, _) => {
-            // needs to be a MaybeUninit
-            match_def_path(cx, adt.did, &paths::MEM_MAYBEUNINIT)
-        },
+        ty::Adt(ref adt, _) => match_def_path(cx, adt.did, &paths::MEM_MAYBEUNINIT),
         _ => false,
     }
 }
@@ -3326,7 +3323,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>(
 /// Given a `Result<T, E>` type, return its error type (`E`).
 fn get_error_type<'a>(cx: &LateContext<'_, '_>, ty: Ty<'a>) -> Option<Ty<'a>> {
     match ty.kind {
-        ty::Adt(_, substs) if match_type(cx, ty, &paths::RESULT) => substs.types().nth(1),
+        ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym!(result_type)) => substs.types().nth(1),
         _ => None,
     }
 }
diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs
index 2fd4bb1db65c..35d481cf666e 100644
--- a/clippy_lints/src/methods/option_map_unwrap_or.rs
+++ b/clippy_lints/src/methods/option_map_unwrap_or.rs
@@ -1,5 +1,5 @@
-use crate::utils::{differing_macro_contexts, paths, snippet_with_applicability, span_lint_and_then};
-use crate::utils::{is_copy, match_type};
+use crate::utils::{differing_macro_contexts, snippet_with_applicability, span_lint_and_then};
+use crate::utils::{is_copy, is_type_diagnostic_item};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_path, NestedVisitorMap, Visitor};
@@ -20,7 +20,7 @@ pub(super) fn lint<'a, 'tcx>(
     map_span: Span,
 ) {
     // lint if the caller of `map()` is an `Option`
-    if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) {
+    if is_type_diagnostic_item(cx, cx.tables.expr_ty(&map_args[0]), sym!(option_type)) {
         if !is_copy(cx, cx.tables.expr_ty(&unwrap_args[1])) {
             // Do not lint if the `map` argument uses identifiers in the `map`
             // argument that are also used in the `unwrap_or` argument
diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs
index f054c6ef67d3..28c1d9753093 100644
--- a/clippy_lints/src/question_mark.rs
+++ b/clippy_lints/src/question_mark.rs
@@ -5,10 +5,10 @@ use rustc_hir::{def, BindingAnnotation, Block, Expr, ExprKind, MatchSource, PatK
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
-use crate::utils::paths::{OPTION, OPTION_NONE};
 use crate::utils::sugg::Sugg;
 use crate::utils::{
-    higher, match_def_path, match_qpath, match_type, snippet_with_applicability, span_lint_and_sugg, SpanlessEq,
+    higher, is_type_diagnostic_item, match_def_path, match_qpath, paths, snippet_with_applicability,
+    span_lint_and_sugg, SpanlessEq,
 };
 
 declare_clippy_lint! {
@@ -141,7 +141,7 @@ impl QuestionMark {
     fn is_option(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool {
         let expr_ty = cx.tables.expr_ty(expression);
 
-        match_type(cx, expr_ty, &OPTION)
+        is_type_diagnostic_item(cx, expr_ty, sym!(option_type))
     }
 
     fn expression_returns_none(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool {
@@ -158,7 +158,7 @@ impl QuestionMark {
                 if let Res::Def(DefKind::Ctor(def::CtorOf::Variant, def::CtorKind::Const), def_id) =
                     cx.tables.qpath_res(qp, expression.hir_id)
                 {
-                    return match_def_path(cx, def_id, &OPTION_NONE);
+                    return match_def_path(cx, def_id, &paths::OPTION_NONE);
                 }
 
                 false
diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs
index 67399fb64683..67b69f5243c2 100644
--- a/clippy_lints/src/types.rs
+++ b/clippy_lints/src/types.rs
@@ -420,7 +420,7 @@ impl Types {
                                 return; // don't recurse into the type
                             }
                         }
-                    } else if match_def_path(cx, def_id, &paths::OPTION) {
+                    } else if cx.tcx.is_diagnostic_item(sym!(option_type), def_id) {
                         if match_type_parameter(cx, qpath, &paths::OPTION).is_some() {
                             span_lint(
                                 cx,
diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs
index a3f71be695b5..98dc29507c2e 100644
--- a/clippy_lints/src/unwrap.rs
+++ b/clippy_lints/src/unwrap.rs
@@ -1,4 +1,4 @@
-use crate::utils::{higher::if_block, match_type, paths, span_lint_and_then, usage::is_potentially_mutated};
+use crate::utils::{higher::if_block, is_type_diagnostic_item, span_lint_and_then, usage::is_potentially_mutated};
 use if_chain::if_chain;
 use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, NestedVisitorMap, Visitor};
 use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Path, QPath, UnOp};
@@ -100,7 +100,7 @@ fn collect_unwrap_info<'a, 'tcx>(
             if let ExprKind::MethodCall(method_name, _, args) = &expr.kind;
             if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].kind;
             let ty = cx.tables.expr_ty(&args[0]);
-            if match_type(cx, ty, &paths::OPTION) || match_type(cx, ty, &paths::RESULT);
+            if is_type_diagnostic_item(cx, ty, sym!(option_type)) || is_type_diagnostic_item(cx, ty, sym!(result_type));
             let name = method_name.ident.as_str();
             if ["is_some", "is_none", "is_ok", "is_err"].contains(&&*name);
             then {
diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs
index b79ba345df4f..d93f8a1e5609 100644
--- a/clippy_lints/src/utils/paths.rs
+++ b/clippy_lints/src/utils/paths.rs
@@ -1,8 +1,10 @@
 //! This module contains paths to types and functions Clippy needs to know
 //! about.
+//!
+//! 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 ARC: [&str; 3] = ["alloc", "sync", "Arc"];
 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"];
@@ -59,8 +61,6 @@ pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
 pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"];
 pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
 pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
-pub const MEM_UNINITIALIZED: [&str; 3] = ["core", "mem", "uninitialized"];
-pub const MEM_ZEROED: [&str; 3] = ["core", "mem", "zeroed"];
 pub const MUTEX: [&str; 4] = ["std", "sync", "mutex", "Mutex"];
 pub const MUTEX_GUARD: [&str; 4] = ["std", "sync", "mutex", "MutexGuard"];
 pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];