1
1
use clippy_utils:: diagnostics:: span_lint;
2
2
3
3
use rustc_data_structures:: fx:: FxHashSet ;
4
- use rustc_hir:: {
5
- def:: Res , FnRetTy , GenericArg , GenericArgs , GenericBound , GenericParamKind , Item , ItemKind , Path , PolyTraitRef , Ty ,
6
- TyKind , TypeBindingKind , UseKind ,
7
- } ;
4
+ use rustc_hir:: { def:: Res , Item , ItemKind , PolyTraitRef , TraitBoundModifier , Ty , TyKind , UseKind } ;
8
5
use rustc_lint:: { LateContext , LateLintPass } ;
9
- use rustc_middle:: ty;
10
6
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
11
- use rustc_span:: Symbol ;
7
+ use rustc_span:: { Span , Symbol } ;
12
8
13
9
declare_clippy_lint ! {
14
- /// **What it does:** Denies the configured types in clippy.toml
10
+ /// **What it does:** Denies the configured types in clippy.toml.
15
11
///
16
12
/// **Why is this bad?** Some types are undesirable in certain contexts.
17
13
///
@@ -24,8 +20,16 @@ declare_clippy_lint! {
24
20
/// `disallowed-methods = ["alloc::collections::btree::map::BTreeMap"]` and not
25
21
/// `disallowed-methods = ["std::collections::BTreeMap"]` as you might expect.
26
22
///
23
+ /// N.B. There is no way to ban primitive types.
24
+ ///
27
25
/// **Example:**
28
26
///
27
+ /// An example clippy.toml configuration:
28
+ /// ```toml
29
+ /// # clippy.toml
30
+ /// disallowed-methods = ["alloc::collections::btree::map::BTreeMap"]
31
+ /// ```
32
+ ///
29
33
/// ```rust,ignore
30
34
/// use std::collections::BTreeMap;
31
35
/// // or its use
@@ -58,198 +62,61 @@ impl DisallowedType {
58
62
59
63
impl_lint_pass ! ( DisallowedType => [ DISALLOWED_TYPE ] ) ;
60
64
61
- impl LateLintPass < ' _ > for DisallowedType {
62
- fn check_item ( & mut self , cx : & LateContext < ' _ > , item : & Item < ' _ > ) {
65
+ impl < ' tcx > LateLintPass < ' tcx > for DisallowedType {
66
+ fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' tcx > ) {
63
67
if_chain ! {
64
68
if let ItemKind :: Use ( path, UseKind :: Single ) = & item. kind;
65
69
if let Res :: Def ( _, id) = path. res;
66
70
let use_path = cx. get_def_path( id) ;
67
71
if let Some ( name) = self . disallowed. iter( ) . find( |path| * * path == use_path) ;
68
72
then {
69
- let name = name. iter( )
70
- . map( |s| s. to_ident_string( ) )
71
- . collect:: <Vec <_>>( )
72
- . join( "::" ) ;
73
- span_lint(
74
- cx,
75
- DISALLOWED_TYPE ,
76
- item. span,
77
- & format!( "`{}` is not allowed according to config" , name) ,
78
- ) ;
73
+ emit( cx, name, item. span, ) ;
79
74
}
80
75
}
81
76
}
82
77
83
- fn check_ty ( & mut self , cx : & LateContext < ' _ > , ty : & Ty < ' _ > ) {
84
- walk_to_path ( cx, ty, & self . disallowed ) ;
85
- }
86
- }
87
-
88
- fn walk_to_path ( cx : & LateContext < ' _ > , ty : & Ty < ' _ > , disallowed : & FxHashSet < Vec < Symbol > > ) {
89
- match & ty. kind {
90
- TyKind :: Slice ( t) => walk_to_path ( cx, t, disallowed) ,
91
- TyKind :: Array ( t, c) => {
92
- walk_to_path ( cx, t, disallowed) ;
93
- // TODO: a bit hacky
94
- walk_to_path (
95
- cx,
96
- & Ty {
97
- hir_id : ty. hir_id ,
98
- kind : TyKind :: Typeof ( * c) ,
99
- span : ty. span ,
100
- } ,
101
- disallowed,
102
- ) ;
103
- } ,
104
- TyKind :: Ptr ( mutable) | TyKind :: Rptr ( _, mutable) => walk_to_path ( cx, mutable. ty , disallowed) ,
105
- TyKind :: BareFn ( barefn) => {
106
- for input in barefn. decl . inputs {
107
- walk_to_path ( cx, input, disallowed) ;
108
- }
109
- if let FnRetTy :: Return ( t) = barefn. decl . output {
110
- walk_to_path ( cx, t, disallowed) ;
111
- }
112
- } ,
113
- TyKind :: Tup ( tup) => {
114
- for t in * tup {
115
- walk_to_path ( cx, t, disallowed) ;
116
- }
117
- } ,
118
- TyKind :: Path ( path) => {
119
- if_chain ! {
120
- if let Some ( did) = cx. qpath_res( path, ty. hir_id) . opt_def_id( ) ;
121
- let use_path = cx. get_def_path( did) ;
122
- if let Some ( name) = disallowed. iter( ) . find( |path| * * path == use_path) ;
123
- then {
124
- let name = name. iter( )
125
- . map( |s| s. to_ident_string( ) )
126
- . collect:: <Vec <_>>( )
127
- . join( "::" ) ;
128
- span_lint(
129
- cx,
130
- DISALLOWED_TYPE ,
131
- path. span( ) ,
132
- & format!( "`{}` is not allowed according to config" , name) ,
133
- ) ;
134
- }
135
- }
136
- } ,
137
- TyKind :: OpaqueDef ( _, gen) => {
138
- for arg in * gen {
139
- if let GenericArg :: Type ( t) = arg {
140
- walk_to_path ( cx, t, disallowed) ;
141
- }
142
- }
143
- } ,
144
- TyKind :: TraitObject ( polyref, _, _) => walk_trait_obj ( cx, & polyref. iter ( ) . collect :: < Vec < _ > > ( ) , disallowed) ,
145
- TyKind :: Typeof ( anonconst) => {
146
- if_chain ! {
147
- if let Some ( tyck) = cx. maybe_typeck_results( ) ;
148
- if let Some ( var_ty) = tyck. node_type_opt( anonconst. hir_id) ;
149
- if let ty:: Adt ( ty:: AdtDef { did, .. } , _) = var_ty. kind( ) ;
150
- let use_path = cx. get_def_path( * did) ;
151
- if let Some ( name) = disallowed. iter( ) . find( |path| * * path == use_path) ;
152
- then {
153
- let name = name. iter( )
154
- . map( |s| s. to_ident_string( ) )
155
- . collect:: <Vec <_>>( )
156
- . join( "::" ) ;
157
- span_lint(
158
- cx,
159
- DISALLOWED_TYPE ,
160
- ty. span,
161
- & format!( "`{}` is not allowed according to config" , name) ,
162
- ) ;
163
- }
78
+ fn check_ty ( & mut self , cx : & LateContext < ' tcx > , ty : & ' tcx Ty < ' tcx > ) {
79
+ if_chain ! {
80
+ if let TyKind :: Path ( path) = & ty. kind;
81
+ if let Some ( did) = cx. qpath_res( path, ty. hir_id) . opt_def_id( ) ;
82
+ let use_path = cx. get_def_path( did) ;
83
+ if let Some ( name) = self . disallowed. iter( ) . find( |path| * * path == use_path) ;
84
+ then {
85
+ emit( cx, name, path. span( ) ) ;
164
86
}
165
- } ,
166
- TyKind :: Infer | TyKind :: Never | TyKind :: Err => { } ,
167
- }
168
- }
169
-
170
- fn walk_path_segments ( cx : & LateContext < ' _ > , path : & Path < ' _ > , disallowed : & FxHashSet < Vec < Symbol > > ) {
171
- for arg in path. segments . iter ( ) . filter_map ( |s| s. args ) {
172
- walk_gen_args ( cx, arg, disallowed) ;
87
+ }
173
88
}
174
- }
175
89
176
- fn walk_trait_obj ( cx : & LateContext < ' _ > , poly : & [ & PolyTraitRef < ' _ > ] , disallowed : & FxHashSet < Vec < Symbol > > ) {
177
- for poly in poly {
90
+ fn check_poly_trait_ref ( & mut self , cx : & LateContext < ' tcx > , poly : & ' tcx PolyTraitRef < ' tcx > , _: TraitBoundModifier ) {
178
91
if_chain ! {
179
92
if let Res :: Def ( _, did) = poly. trait_ref. path. res;
180
93
let use_path = cx. get_def_path( did) ;
181
- if let Some ( name) = disallowed. iter( ) . find( |path| * * path == use_path) ;
94
+ if let Some ( name) = self . disallowed. iter( ) . find( |path| * * path == use_path) ;
182
95
then {
183
- let name = name. iter( )
184
- . map( |s| s. to_ident_string( ) )
185
- . collect:: <Vec <_>>( )
186
- . join( "::" ) ;
187
- span_lint(
188
- cx,
189
- DISALLOWED_TYPE ,
190
- poly. trait_ref. path. span,
191
- & format!( "`{}` is not allowed according to config" , name) ,
192
- ) ;
193
- }
194
- }
195
- walk_path_segments ( cx, poly. trait_ref . path , disallowed) ;
196
-
197
- for param in poly. bound_generic_params {
198
- walk_gen_bounds ( cx, param. bounds , disallowed) ;
199
- match param. kind {
200
- GenericParamKind :: Type { default : Some ( ty) , .. } => walk_to_path ( cx, ty, disallowed) ,
201
- GenericParamKind :: Const {
202
- ty,
203
- default : Some ( anon) ,
204
- } => {
205
- walk_to_path ( cx, ty, disallowed) ;
206
- walk_to_path (
207
- cx,
208
- & Ty {
209
- hir_id : ty. hir_id ,
210
- kind : TyKind :: Typeof ( anon) ,
211
- span : ty. span ,
212
- } ,
213
- disallowed,
214
- ) ;
215
- } ,
216
- _ => { } ,
96
+ emit( cx, name, poly. trait_ref. path. span) ;
217
97
}
218
98
}
219
99
}
220
- }
221
100
222
- fn walk_gen_args ( cx : & LateContext < ' _ > , gen_args : & GenericArgs < ' _ > , disallowed : & FxHashSet < Vec < Symbol > > ) {
223
- for arg in gen_args. args {
224
- match arg {
225
- GenericArg :: Type ( t) => walk_to_path ( cx, t, disallowed) ,
226
- GenericArg :: Const ( c) => walk_to_path (
227
- cx,
228
- & Ty {
229
- hir_id : c. value . hir_id ,
230
- kind : TyKind :: Typeof ( c. value ) ,
231
- span : c. span ,
232
- } ,
233
- disallowed,
234
- ) ,
235
- GenericArg :: Lifetime ( _) => { } ,
236
- }
237
- }
238
- for bind in gen_args. bindings {
239
- match bind. kind {
240
- TypeBindingKind :: Equality { ty } => walk_to_path ( cx, ty, disallowed) ,
241
- TypeBindingKind :: Constraint { bounds } => walk_gen_bounds ( cx, bounds, disallowed) ,
242
- }
243
- walk_gen_args ( cx, bind. gen_args , disallowed) ;
244
- }
101
+ // TODO: if non primitive const generics are a thing
102
+ // fn check_generic_arg(&mut self, cx: &LateContext<'tcx>, arg: &'tcx GenericArg<'tcx>) {
103
+ // match arg {
104
+ // GenericArg::Const(c) => {},
105
+ // }
106
+ // }
107
+ // fn check_generic_param(&mut self, cx: &LateContext<'tcx>, param: &'tcx GenericParam<'tcx>) {
108
+ // match param.kind {
109
+ // GenericParamKind::Const { .. } => {},
110
+ // }
111
+ // }
245
112
}
246
113
247
- fn walk_gen_bounds ( cx : & LateContext < ' _ > , bounds : & [ GenericBound < ' _ > ] , disallowed : & FxHashSet < Vec < Symbol > > ) {
248
- for b in bounds {
249
- match b {
250
- GenericBound :: Trait ( poly , _ ) => walk_trait_obj ( cx , & [ poly ] , disallowed ) ,
251
- GenericBound :: LangItemTrait ( _ , _ , _ , gen ) => walk_gen_args ( cx , gen , disallowed ) ,
252
- GenericBound :: Outlives ( _ ) => { } ,
253
- }
254
- }
114
+ fn emit ( cx : & LateContext < ' _ > , name : & [ Symbol ] , span : Span ) {
115
+ let name = name . iter ( ) . map ( |s| s . to_ident_string ( ) ) . collect :: < Vec < _ > > ( ) . join ( "::" ) ;
116
+ span_lint (
117
+ cx ,
118
+ DISALLOWED_TYPE ,
119
+ span ,
120
+ & format ! ( "`{}` is not allowed according to config" , name ) ,
121
+ ) ;
255
122
}
0 commit comments