]> git.lizzy.rs Git - rust.git/blobdiff - src/tools/clippy/clippy_lints/src/disallowed_type.rs
Rollup merge of #87166 - de-vri-es:show-discriminant-before-overflow, r=jackh726
[rust.git] / src / tools / clippy / clippy_lints / src / disallowed_type.rs
index e4a88c6324ebfdac3958c208b1d2251194deb6e4..e627168b9327566fb67015d9652c5c9f762a28c9 100644 (file)
@@ -2,27 +2,24 @@
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::{
-    def::Res, def_id::DefId, Crate, Item, ItemKind, PolyTraitRef, TraitBoundModifier, Ty, TyKind, UseKind,
+    def::Res, def_id::DefId, Crate, Item, ItemKind, PolyTraitRef, PrimTy, TraitBoundModifier, Ty, TyKind, UseKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{Span, Symbol};
 
 declare_clippy_lint! {
-    /// **What it does:** Denies the configured types in clippy.toml.
+    /// ### What it does
+    /// Denies the configured types in clippy.toml.
     ///
-    /// **Why is this bad?** Some types are undesirable in certain contexts.
-    ///
-    /// **Known problems:** None.
-    ///
-    /// N.B. There is no way to ban primitive types.
-    ///
-    /// **Example:**
+    /// ### Why is this bad?
+    /// Some types are undesirable in certain contexts.
     ///
+    /// ### Example:
     /// An example clippy.toml configuration:
     /// ```toml
     /// # clippy.toml
-    /// disallowed-methods = ["std::collections::BTreeMap"]
+    /// disallowed-types = ["std::collections::BTreeMap"]
     /// ```
     ///
     /// ```rust,ignore
@@ -42,7 +39,8 @@
 #[derive(Clone, Debug)]
 pub struct DisallowedType {
     disallowed: FxHashSet<Vec<Symbol>>,
-    def_ids: FxHashSet<(DefId, Vec<Symbol>)>,
+    def_ids: FxHashSet<DefId>,
+    prim_tys: FxHashSet<PrimTy>,
 }
 
 impl DisallowedType {
@@ -53,6 +51,23 @@ pub fn new(disallowed: &FxHashSet<String>) -> Self {
                 .map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>())
                 .collect(),
             def_ids: FxHashSet::default(),
+            prim_tys: FxHashSet::default(),
+        }
+    }
+
+    fn check_res_emit(&self, cx: &LateContext<'_>, res: &Res, span: Span) {
+        match res {
+            Res::Def(_, did) => {
+                if self.def_ids.contains(did) {
+                    emit(cx, &cx.tcx.def_path_str(*did), span);
+                }
+            },
+            Res::PrimTy(prim) => {
+                if self.prim_tys.contains(prim) {
+                    emit(cx, prim.name_str(), span);
+                }
+            },
+            _ => {},
         }
     }
 }
@@ -63,60 +78,36 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedType {
     fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
         for path in &self.disallowed {
             let segs = path.iter().map(ToString::to_string).collect::<Vec<_>>();
-            if let Res::Def(_, id) = clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>())
-            {
-                self.def_ids.insert((id, path.clone()));
+            match clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>()) {
+                Res::Def(_, id) => {
+                    self.def_ids.insert(id);
+                },
+                Res::PrimTy(ty) => {
+                    self.prim_tys.insert(ty);
+                },
+                _ => {},
             }
         }
     }
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
-        if_chain! {
-            if let ItemKind::Use(path, UseKind::Single) = &item.kind;
-            if let Res::Def(_, did) = path.res;
-            if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
-            then {
-                emit(cx, name, item.span,);
-            }
+        if let ItemKind::Use(path, UseKind::Single) = &item.kind {
+            self.check_res_emit(cx, &path.res, item.span);
         }
     }
 
     fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
-        if_chain! {
-            if let TyKind::Path(path) = &ty.kind;
-            if let Some(did) = cx.qpath_res(path, ty.hir_id).opt_def_id();
-            if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
-            then {
-                emit(cx, name, path.span());
-            }
+        if let TyKind::Path(path) = &ty.kind {
+            self.check_res_emit(cx, &cx.qpath_res(path, ty.hir_id), ty.span);
         }
     }
 
     fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>, _: TraitBoundModifier) {
-        if_chain! {
-            if let Res::Def(_, did) = poly.trait_ref.path.res;
-            if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
-            then {
-                emit(cx, name, poly.trait_ref.path.span);
-            }
-        }
+        self.check_res_emit(cx, &poly.trait_ref.path.res, poly.trait_ref.path.span);
     }
-
-    // TODO: if non primitive const generics are a thing
-    // fn check_generic_arg(&mut self, cx: &LateContext<'tcx>, arg: &'tcx GenericArg<'tcx>) {
-    //     match arg {
-    //         GenericArg::Const(c) => {},
-    //     }
-    // }
-    // fn check_generic_param(&mut self, cx: &LateContext<'tcx>, param: &'tcx GenericParam<'tcx>) {
-    //     match param.kind {
-    //         GenericParamKind::Const { .. } => {},
-    //     }
-    // }
 }
 
-fn emit(cx: &LateContext<'_>, name: &[Symbol], span: Span) {
-    let name = name.iter().map(|s| s.to_ident_string()).collect::<Vec<_>>().join("::");
+fn emit(cx: &LateContext<'_>, name: &str, span: Span) {
     span_lint(
         cx,
         DISALLOWED_TYPE,