@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint;
22
33use rustc_data_structures:: fx:: FxHashSet ;
44use rustc_hir:: {
5- def:: Res , def_id:: DefId , Crate , Item , ItemKind , PolyTraitRef , TraitBoundModifier , Ty , TyKind , UseKind ,
5+ def:: Res , def_id:: DefId , Crate , Item , ItemKind , PolyTraitRef , PrimTy , TraitBoundModifier , Ty , TyKind , UseKind ,
66} ;
77use rustc_lint:: { LateContext , LateLintPass } ;
88use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
@@ -15,14 +15,12 @@ declare_clippy_lint! {
1515 ///
1616 /// **Known problems:** None.
1717 ///
18- /// N.B. There is no way to ban primitive types.
19- ///
2018 /// **Example:**
2119 ///
2220 /// An example clippy.toml configuration:
2321 /// ```toml
2422 /// # clippy.toml
25- /// disallowed-methods = ["std::collections::BTreeMap"]
23+ /// disallowed-types = ["std::collections::BTreeMap"]
2624 /// ```
2725 ///
2826 /// ```rust,ignore
@@ -42,7 +40,8 @@ declare_clippy_lint! {
4240#[ derive( Clone , Debug ) ]
4341pub struct DisallowedType {
4442 disallowed : FxHashSet < Vec < Symbol > > ,
45- def_ids : FxHashSet < ( DefId , Vec < Symbol > ) > ,
43+ def_ids : FxHashSet < DefId > ,
44+ prim_tys : FxHashSet < PrimTy > ,
4645}
4746
4847impl DisallowedType {
@@ -53,6 +52,23 @@ impl DisallowedType {
5352 . map ( |s| s. split ( "::" ) . map ( |seg| Symbol :: intern ( seg) ) . collect :: < Vec < _ > > ( ) )
5453 . collect ( ) ,
5554 def_ids : FxHashSet :: default ( ) ,
55+ prim_tys : FxHashSet :: default ( ) ,
56+ }
57+ }
58+
59+ fn check_res_emit ( & self , cx : & LateContext < ' _ > , res : & Res , span : Span ) {
60+ match res {
61+ Res :: Def ( _, did) => {
62+ if self . def_ids . contains ( did) {
63+ emit ( cx, & cx. tcx . def_path_str ( * did) , span) ;
64+ }
65+ } ,
66+ Res :: PrimTy ( prim) => {
67+ if self . prim_tys . contains ( prim) {
68+ emit ( cx, prim. name_str ( ) , span) ;
69+ }
70+ } ,
71+ _ => { } ,
5672 }
5773 }
5874}
@@ -63,60 +79,36 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedType {
6379 fn check_crate ( & mut self , cx : & LateContext < ' _ > , _: & Crate < ' _ > ) {
6480 for path in & self . disallowed {
6581 let segs = path. iter ( ) . map ( ToString :: to_string) . collect :: < Vec < _ > > ( ) ;
66- if let Res :: Def ( _, id) = clippy_utils:: path_to_res ( cx, & segs. iter ( ) . map ( String :: as_str) . collect :: < Vec < _ > > ( ) )
67- {
68- self . def_ids . insert ( ( id, path. clone ( ) ) ) ;
82+ match clippy_utils:: path_to_res ( cx, & segs. iter ( ) . map ( String :: as_str) . collect :: < Vec < _ > > ( ) ) {
83+ Res :: Def ( _, id) => {
84+ self . def_ids . insert ( id) ;
85+ } ,
86+ Res :: PrimTy ( ty) => {
87+ self . prim_tys . insert ( ty) ;
88+ } ,
89+ _ => { } ,
6990 }
7091 }
7192 }
7293
7394 fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) {
74- if_chain ! {
75- if let ItemKind :: Use ( path, UseKind :: Single ) = & item. kind;
76- if let Res :: Def ( _, did) = path. res;
77- if let Some ( ( _, name) ) = self . def_ids. iter( ) . find( |( id, _) | * id == did) ;
78- then {
79- emit( cx, name, item. span, ) ;
80- }
95+ if let ItemKind :: Use ( path, UseKind :: Single ) = & item. kind {
96+ self . check_res_emit ( cx, & path. res , item. span ) ;
8197 }
8298 }
8399
84100 fn check_ty ( & mut self , cx : & LateContext < ' tcx > , ty : & ' tcx Ty < ' tcx > ) {
85- if_chain ! {
86- if let TyKind :: Path ( path) = & ty. kind;
87- if let Some ( did) = cx. qpath_res( path, ty. hir_id) . opt_def_id( ) ;
88- if let Some ( ( _, name) ) = self . def_ids. iter( ) . find( |( id, _) | * id == did) ;
89- then {
90- emit( cx, name, path. span( ) ) ;
91- }
101+ if let TyKind :: Path ( path) = & ty. kind {
102+ self . check_res_emit ( cx, & cx. qpath_res ( path, ty. hir_id ) , ty. span ) ;
92103 }
93104 }
94105
95106 fn check_poly_trait_ref ( & mut self , cx : & LateContext < ' tcx > , poly : & ' tcx PolyTraitRef < ' tcx > , _: TraitBoundModifier ) {
96- if_chain ! {
97- if let Res :: Def ( _, did) = poly. trait_ref. path. res;
98- if let Some ( ( _, name) ) = self . def_ids. iter( ) . find( |( id, _) | * id == did) ;
99- then {
100- emit( cx, name, poly. trait_ref. path. span) ;
101- }
102- }
107+ self . check_res_emit ( cx, & poly. trait_ref . path . res , poly. trait_ref . path . span ) ;
103108 }
104-
105- // TODO: if non primitive const generics are a thing
106- // fn check_generic_arg(&mut self, cx: &LateContext<'tcx>, arg: &'tcx GenericArg<'tcx>) {
107- // match arg {
108- // GenericArg::Const(c) => {},
109- // }
110- // }
111- // fn check_generic_param(&mut self, cx: &LateContext<'tcx>, param: &'tcx GenericParam<'tcx>) {
112- // match param.kind {
113- // GenericParamKind::Const { .. } => {},
114- // }
115- // }
116109}
117110
118- fn emit ( cx : & LateContext < ' _ > , name : & [ Symbol ] , span : Span ) {
119- let name = name. iter ( ) . map ( |s| s. to_ident_string ( ) ) . collect :: < Vec < _ > > ( ) . join ( "::" ) ;
111+ fn emit ( cx : & LateContext < ' _ > , name : & str , span : Span ) {
120112 span_lint (
121113 cx,
122114 DISALLOWED_TYPE ,
0 commit comments