about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCameron Steffen <cam.steffen94@gmail.com>2022-01-05 20:56:29 -0600
committerCameron Steffen <cam.steffen94@gmail.com>2022-01-28 15:45:41 -0600
commit66a83d33ea9a39d1fc0f4c2ca058c0ce4884a71a (patch)
treee0d2f4adff82f82a151a8f1b21f01f1abbb3dd55
parent145d7fc5298cec0995bdc4e71d09d275fcbcdcdb (diff)
downloadrust-66a83d33ea9a39d1fc0f4c2ca058c0ce4884a71a.tar.gz
rust-66a83d33ea9a39d1fc0f4c2ca058c0ce4884a71a.zip
Factor out some ty param utils
-rw-r--r--clippy_lints/src/types/box_collection.rs27
-rw-r--r--clippy_lints/src/types/option_option.rs30
-rw-r--r--clippy_lints/src/types/rc_buffer.rs33
-rw-r--r--clippy_lints/src/types/rc_mutex.rs6
-rw-r--r--clippy_lints/src/types/redundant_allocation.rs19
-rw-r--r--clippy_utils/src/lib.rs38
6 files changed, 63 insertions, 90 deletions
diff --git a/clippy_lints/src/types/box_collection.rs b/clippy_lints/src/types/box_collection.rs
index 538c10a5b20..21a9558ec07 100644
--- a/clippy_lints/src/types/box_collection.rs
+++ b/clippy_lints/src/types/box_collection.rs
@@ -1,8 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::is_ty_param_diagnostic_item;
+use clippy_utils::{path_def_id, qpath_generic_tys};
 use rustc_hir::{self as hir, def_id::DefId, QPath};
 use rustc_lint::LateContext;
-use rustc_span::symbol::sym;
+use rustc_span::{sym, Symbol};
 
 use super::BOX_COLLECTION;
 
@@ -11,10 +11,9 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
         if Some(def_id) == cx.tcx.lang_items().owned_box();
         if let Some(item_type) = get_std_collection(cx, qpath);
         then {
-            let generic = if item_type == "String" {
-                ""
-            } else {
-                "<..>"
+            let generic = match item_type {
+                sym::String => "",
+                _ => "<..>",
             };
             span_lint_and_help(
                 cx,
@@ -37,14 +36,10 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
     }
 }
 
-fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
-    if is_ty_param_diagnostic_item(cx, qpath, sym::Vec).is_some() {
-        Some("Vec")
-    } else if is_ty_param_diagnostic_item(cx, qpath, sym::String).is_some() {
-        Some("String")
-    } else if is_ty_param_diagnostic_item(cx, qpath, sym::HashMap).is_some() {
-        Some("HashMap")
-    } else {
-        None
-    }
+fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol> {
+    let param = qpath_generic_tys(qpath).next()?;
+    let id = path_def_id(cx, param)?;
+    cx.tcx
+        .get_diagnostic_name(id)
+        .filter(|&name| matches!(name, sym::HashMap | sym::String | sym::Vec))
 }
diff --git a/clippy_lints/src/types/option_option.rs b/clippy_lints/src/types/option_option.rs
index 903e62995c6..8767e3c30a6 100644
--- a/clippy_lints/src/types/option_option.rs
+++ b/clippy_lints/src/types/option_option.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_ty_param_diagnostic_item;
+use clippy_utils::{path_def_id, qpath_generic_tys};
+use if_chain::if_chain;
 use rustc_hir::{self as hir, def_id::DefId, QPath};
 use rustc_lint::LateContext;
 use rustc_span::symbol::sym;
@@ -7,16 +8,21 @@ use rustc_span::symbol::sym;
 use super::OPTION_OPTION;
 
 pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
-    if cx.tcx.is_diagnostic_item(sym::Option, def_id) && is_ty_param_diagnostic_item(cx, qpath, sym::Option).is_some() {
-        span_lint(
-            cx,
-            OPTION_OPTION,
-            hir_ty.span,
-            "consider using `Option<T>` instead of `Option<Option<T>>` or a custom \
-                                 enum if you need to distinguish all 3 cases",
-        );
-        true
-    } else {
-        false
+    if_chain! {
+        if cx.tcx.is_diagnostic_item(sym::Option, def_id);
+        if let Some(arg) = qpath_generic_tys(qpath).next();
+        if path_def_id(cx, arg) == Some(def_id);
+        then {
+            span_lint(
+                cx,
+                OPTION_OPTION,
+                hir_ty.span,
+                "consider using `Option<T>` instead of `Option<Option<T>>` or a custom \
+                                     enum if you need to distinguish all 3 cases",
+            );
+            true
+        } else {
+            false
+        }
     }
 }
diff --git a/clippy_lints/src/types/rc_buffer.rs b/clippy_lints/src/types/rc_buffer.rs
index 0a2df7d2188..4d72a29e8c7 100644
--- a/clippy_lints/src/types/rc_buffer.rs
+++ b/clippy_lints/src/types/rc_buffer.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{is_ty_param_diagnostic_item, qpath_generic_tys};
+use clippy_utils::{path_def_id, qpath_generic_tys};
 use rustc_errors::Applicability;
 use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind};
 use rustc_lint::LateContext;
@@ -20,7 +20,12 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
                 format!("Rc<{}>", alternate),
                 Applicability::MachineApplicable,
             );
-        } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Vec) {
+        } else {
+            let Some(ty) = qpath_generic_tys(qpath).next() else { return false };
+            let Some(id) = path_def_id(cx, ty) else { return false };
+            if !cx.tcx.is_diagnostic_item(sym::Vec, id) {
+                return false;
+            }
             let qpath = match &ty.kind {
                 TyKind::Path(qpath) => qpath,
                 _ => return false,
@@ -55,7 +60,11 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
                 format!("Arc<{}>", alternate),
                 Applicability::MachineApplicable,
             );
-        } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Vec) {
+        } else if let Some(ty) = qpath_generic_tys(qpath).next() {
+            let Some(id) = path_def_id(cx, ty) else { return false };
+            if !cx.tcx.is_diagnostic_item(sym::Vec, id) {
+                return false;
+            }
             let qpath = match &ty.kind {
                 TyKind::Path(qpath) => qpath,
                 _ => return false,
@@ -85,13 +94,13 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
 }
 
 fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
-    if is_ty_param_diagnostic_item(cx, qpath, sym::String).is_some() {
-        Some("str")
-    } else if is_ty_param_diagnostic_item(cx, qpath, sym::OsString).is_some() {
-        Some("std::ffi::OsStr")
-    } else if is_ty_param_diagnostic_item(cx, qpath, sym::PathBuf).is_some() {
-        Some("std::path::Path")
-    } else {
-        None
-    }
+    let ty = qpath_generic_tys(qpath).next()?;
+    let id = path_def_id(cx, ty)?;
+    let path = match cx.tcx.get_diagnostic_name(id)? {
+        sym::String => "str",
+        sym::OsString => "std::ffi::OsStr",
+        sym::PathBuf => "std::path::Path",
+        _ => return None,
+    };
+    Some(path)
 }
diff --git a/clippy_lints/src/types/rc_mutex.rs b/clippy_lints/src/types/rc_mutex.rs
index d54608a07bb..a75972cf3dd 100644
--- a/clippy_lints/src/types/rc_mutex.rs
+++ b/clippy_lints/src/types/rc_mutex.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::is_ty_param_diagnostic_item;
+use clippy_utils::{path_def_id, qpath_generic_tys};
 use if_chain::if_chain;
 use rustc_hir::{self as hir, def_id::DefId, QPath};
 use rustc_lint::LateContext;
@@ -10,7 +10,9 @@ use super::RC_MUTEX;
 pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
     if_chain! {
         if cx.tcx.is_diagnostic_item(sym::Rc, def_id) ;
-        if let Some(_) = is_ty_param_diagnostic_item(cx, qpath, sym::Mutex) ;
+        if let Some(arg) = qpath_generic_tys(qpath).next();
+        if let Some(id) = path_def_id(cx, arg);
+        if cx.tcx.is_diagnostic_item(sym::Mutex, id);
         then {
             span_lint_and_help(
                 cx,
diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs
index 8638197a584..10d2ae2eb1d 100644
--- a/clippy_lints/src/types/redundant_allocation.rs
+++ b/clippy_lints/src/types/redundant_allocation.rs
@@ -1,8 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{snippet, snippet_with_applicability};
-use clippy_utils::{is_ty_param_diagnostic_item, is_ty_param_lang_item, qpath_generic_tys};
+use clippy_utils::{path_def_id, qpath_generic_tys};
 use rustc_errors::Applicability;
-use rustc_hir::{self as hir, def_id::DefId, LangItem, QPath, TyKind};
+use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind};
 use rustc_lint::LateContext;
 use rustc_span::symbol::sym;
 
@@ -39,14 +39,13 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
         return true;
     }
 
-    let (inner_sym, ty) = if let Some(ty) = is_ty_param_lang_item(cx, qpath, LangItem::OwnedBox) {
-        ("Box", ty)
-    } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Rc) {
-        ("Rc", ty)
-    } else if let Some(ty) = is_ty_param_diagnostic_item(cx, qpath, sym::Arc) {
-        ("Arc", ty)
-    } else {
-        return false;
+    let Some(ty) = qpath_generic_tys(qpath).next() else { return false };
+    let Some(id) = path_def_id(cx, ty) else { return false };
+    let (inner_sym, ty) = match cx.tcx.get_diagnostic_name(id) {
+        Some(sym::Arc) => ("Arc", ty),
+        Some(sym::Rc) => ("Rc", ty),
+        _ if Some(id) == cx.tcx.lang_items().owned_box() => ("Box", ty),
+        _ => return false,
     };
 
     let inner_qpath = match &ty.kind {
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 82d50238666..ed73364841c 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -262,44 +262,6 @@ pub fn is_wild(pat: &Pat<'_>) -> bool {
     matches!(pat.kind, PatKind::Wild)
 }
 
-/// Checks if the first type parameter is a lang item.
-pub fn is_ty_param_lang_item<'tcx>(
-    cx: &LateContext<'_>,
-    qpath: &QPath<'tcx>,
-    item: LangItem,
-) -> Option<&'tcx hir::Ty<'tcx>> {
-    let ty = qpath_generic_tys(qpath).next()?;
-
-    if let TyKind::Path(qpath) = &ty.kind {
-        cx.qpath_res(qpath, ty.hir_id)
-            .opt_def_id()
-            .map_or(false, |id| {
-                cx.tcx.lang_items().require(item).map_or(false, |lang_id| id == lang_id)
-            })
-            .then(|| ty)
-    } else {
-        None
-    }
-}
-
-/// Checks if the first type parameter is a diagnostic item.
-pub fn is_ty_param_diagnostic_item<'tcx>(
-    cx: &LateContext<'_>,
-    qpath: &QPath<'tcx>,
-    item: Symbol,
-) -> Option<&'tcx hir::Ty<'tcx>> {
-    let ty = qpath_generic_tys(qpath).next()?;
-
-    if let TyKind::Path(qpath) = &ty.kind {
-        cx.qpath_res(qpath, ty.hir_id)
-            .opt_def_id()
-            .map_or(false, |id| cx.tcx.is_diagnostic_item(item, id))
-            .then(|| ty)
-    } else {
-        None
-    }
-}
-
 /// Checks if the method call given in `expr` belongs to the given trait.
 /// This is a deprecated function, consider using [`is_trait_method`].
 pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool {