@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint;
2
2
3
3
use rustc_data_structures:: fx:: FxHashSet ;
4
4
use 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 ,
6
6
} ;
7
7
use rustc_lint:: { LateContext , LateLintPass } ;
8
8
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
@@ -15,14 +15,12 @@ declare_clippy_lint! {
15
15
///
16
16
/// **Known problems:** None.
17
17
///
18
- /// N.B. There is no way to ban primitive types.
19
- ///
20
18
/// **Example:**
21
19
///
22
20
/// An example clippy.toml configuration:
23
21
/// ```toml
24
22
/// # clippy.toml
25
- /// disallowed-methods = ["std::collections::BTreeMap"]
23
+ /// disallowed-types = ["std::collections::BTreeMap"]
26
24
/// ```
27
25
///
28
26
/// ```rust,ignore
@@ -42,7 +40,8 @@ declare_clippy_lint! {
42
40
#[ derive( Clone , Debug ) ]
43
41
pub struct DisallowedType {
44
42
disallowed : FxHashSet < Vec < Symbol > > ,
45
- def_ids : FxHashSet < ( DefId , Vec < Symbol > ) > ,
43
+ def_ids : FxHashSet < DefId > ,
44
+ prim_tys : FxHashSet < PrimTy > ,
46
45
}
47
46
48
47
impl DisallowedType {
@@ -53,6 +52,23 @@ impl DisallowedType {
53
52
. map ( |s| s. split ( "::" ) . map ( |seg| Symbol :: intern ( seg) ) . collect :: < Vec < _ > > ( ) )
54
53
. collect ( ) ,
55
54
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
+ _ => { } ,
56
72
}
57
73
}
58
74
}
@@ -63,60 +79,36 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedType {
63
79
fn check_crate ( & mut self , cx : & LateContext < ' _ > , _: & Crate < ' _ > ) {
64
80
for path in & self . disallowed {
65
81
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
+ _ => { } ,
69
90
}
70
91
}
71
92
}
72
93
73
94
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 ) ;
81
97
}
82
98
}
83
99
84
100
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 ) ;
92
103
}
93
104
}
94
105
95
106
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 ) ;
103
108
}
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
- // }
116
109
}
117
110
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 ) {
120
112
span_lint (
121
113
cx,
122
114
DISALLOWED_TYPE ,
0 commit comments