]> git.lizzy.rs Git - rust.git/commitdiff
Factor out some ty param utils
authorCameron Steffen <cam.steffen94@gmail.com>
Thu, 6 Jan 2022 02:56:29 +0000 (20:56 -0600)
committerCameron Steffen <cam.steffen94@gmail.com>
Fri, 28 Jan 2022 21:45:41 +0000 (15:45 -0600)
clippy_lints/src/types/box_collection.rs
clippy_lints/src/types/option_option.rs
clippy_lints/src/types/rc_buffer.rs
clippy_lints/src/types/rc_mutex.rs
clippy_lints/src/types/redundant_allocation.rs
clippy_utils/src/lib.rs

index 538c10a5b2045403640a0cae49cb1ce8ba9db760..21a9558ec076a54e938fadc06f56fb6f9fa5ee34 100644 (file)
@@ -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))
 }
index 903e62995c61702be4775eb152c9674a5e25486b..8767e3c30a68ac4564ba72814b48f53719090be3 100644 (file)
@@ -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 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
+        }
     }
 }
index 0a2df7d21883561dada1a46e75bf4c4acf727b1a..4d72a29e8c74722711aeb3b6a754e3d0c2bd4765 100644 (file)
@@ -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)
 }
index d54608a07bb27e70a5432be150f6fcd137b9653e..a75972cf3ddbe1e2d91acbf11fc541577c7ed7e5 100644 (file)
@@ -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 @@
 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,
index 8638197a5842f68317f1137ea3330899cfead3eb..10d2ae2eb1dbb8808eb0fa601d0fc1ffad349dfb 100644 (file)
@@ -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 {
index 82d5023866684b796c9ebdb425c7df4aa266b3ee..ed73364841c598fb8483bffe10aa17ccc3eb14ca 100644 (file)
@@ -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 {