1
- use crate :: rustc:: lint:: { LateContext , LateLintPass , LintArray , LintPass , EarlyContext , EarlyLintPass } ;
2
- use crate :: rustc:: { declare_tool_lint, lint_array} ;
3
- use crate :: rustc:: hir:: * ;
1
+ use crate :: utils:: {
2
+ match_qpath, match_type, paths, span_help_and_lint, span_lint, span_lint_and_sugg, walk_ptrs_ty,
3
+ } ;
4
+ use if_chain:: if_chain;
4
5
use crate :: rustc:: hir;
5
6
use crate :: rustc:: hir:: intravisit:: { walk_expr, NestedVisitorMap , Visitor } ;
7
+ use crate :: rustc:: hir:: * ;
8
+ use crate :: rustc:: lint:: { EarlyContext , EarlyLintPass , LateContext , LateLintPass , LintArray , LintPass } ;
9
+ use crate :: rustc:: { declare_tool_lint, lint_array} ;
6
10
use crate :: rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
7
- use crate :: utils:: { match_qpath, paths, span_lint, span_lint_and_sugg} ;
8
- use crate :: syntax:: symbol:: LocalInternedString ;
9
11
use crate :: syntax:: ast:: { Crate as AstCrate , Ident , ItemKind , Name } ;
10
12
use crate :: syntax:: source_map:: Span ;
11
-
13
+ use crate :: syntax :: symbol :: LocalInternedString ;
12
14
13
15
/// **What it does:** Checks for various things we like to keep tidy in clippy.
14
16
///
@@ -23,7 +25,6 @@ declare_clippy_lint! {
23
25
"various things that will negatively affect your clippy experience"
24
26
}
25
27
26
-
27
28
/// **What it does:** Ensures every lint is associated to a `LintPass`.
28
29
///
29
30
/// **Why is this bad?** The compiler only knows lints via a `LintPass`. Without
@@ -53,7 +54,6 @@ declare_clippy_lint! {
53
54
"declaring a lint without associating it in a LintPass"
54
55
}
55
56
56
-
57
57
/// **What it does:** Checks for the presence of the default hash types "HashMap" or "HashSet"
58
58
/// and recommends the FxHash* variants.
59
59
///
@@ -65,6 +65,29 @@ declare_clippy_lint! {
65
65
"forbid HashMap and HashSet and suggest the FxHash* variants"
66
66
}
67
67
68
+ /// **What it does:** Checks for calls to `cx.span_lint*` and suggests to use the `utils::*`
69
+ /// variant of the function.
70
+ ///
71
+ /// **Why is this bad?** The `utils::*` variants also add a link to the Clippy documentation to the
72
+ /// warning/error messages.
73
+ ///
74
+ /// **Known problems:** None.
75
+ ///
76
+ /// **Example:**
77
+ /// Bad:
78
+ /// ```rust
79
+ /// cx.span_lint(LINT_NAME, "message");
80
+ /// ```
81
+ ///
82
+ /// Good:
83
+ /// ```rust
84
+ /// utils::span_lint(cx, LINT_NAME, "message");
85
+ /// ```
86
+ declare_clippy_lint ! {
87
+ pub COMPILER_LINT_FUNCTIONS ,
88
+ internal,
89
+ "usage of the lint functions of the compiler instead of the utils::* variant"
90
+ }
68
91
69
92
#[ derive( Copy , Clone ) ]
70
93
pub struct Clippy ;
@@ -119,7 +142,6 @@ pub struct LintWithoutLintPass {
119
142
registered_lints : FxHashSet < Name > ,
120
143
}
121
144
122
-
123
145
impl LintPass for LintWithoutLintPass {
124
146
fn get_lints ( & self ) -> LintArray {
125
147
lint_array ! ( LINT_WITHOUT_LINT_PASS )
@@ -171,7 +193,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
171
193
}
172
194
}
173
195
174
-
175
196
fn is_lint_ref_type ( ty : & Ty ) -> bool {
176
197
if let TyKind :: Rptr (
177
198
_,
@@ -188,7 +209,6 @@ fn is_lint_ref_type(ty: &Ty) -> bool {
188
209
false
189
210
}
190
211
191
-
192
212
fn is_lint_array_type ( ty : & Ty ) -> bool {
193
213
if let TyKind :: Path ( ref path) = ty. node {
194
214
match_qpath ( path, & paths:: LINT_ARRAY )
@@ -224,8 +244,8 @@ pub struct DefaultHashTypes {
224
244
impl DefaultHashTypes {
225
245
pub fn default ( ) -> Self {
226
246
let mut map = FxHashMap :: default ( ) ;
227
- map. insert ( "HashMap" . to_owned ( ) , "FxHashMap" . to_owned ( ) ) ;
228
- map. insert ( "HashSet" . to_owned ( ) , "FxHashSet" . to_owned ( ) ) ;
247
+ map. insert ( "HashMap" . to_string ( ) , "FxHashMap" . to_string ( ) ) ;
248
+ map. insert ( "HashSet" . to_string ( ) , "FxHashSet" . to_string ( ) ) ;
229
249
Self { map }
230
250
}
231
251
}
@@ -240,8 +260,62 @@ impl EarlyLintPass for DefaultHashTypes {
240
260
fn check_ident ( & mut self , cx : & EarlyContext < ' _ > , ident : Ident ) {
241
261
let ident_string = ident. to_string ( ) ;
242
262
if let Some ( replace) = self . map . get ( & ident_string) {
243
- let msg = format ! ( "Prefer {} over {}, it has better performance and we don't need any collision prevention in clippy" , replace, ident_string) ;
244
- span_lint_and_sugg ( cx, DEFAULT_HASH_TYPES , ident. span , & msg, "use" , replace. to_owned ( ) ) ;
263
+ let msg = format ! ( "Prefer {} over {}, it has better performance \
264
+ and we don't need any collision prevention in clippy",
265
+ replace, ident_string) ;
266
+ span_lint_and_sugg (
267
+ cx,
268
+ DEFAULT_HASH_TYPES ,
269
+ ident. span ,
270
+ & msg,
271
+ "use" ,
272
+ replace. to_string ( ) ,
273
+ ) ;
274
+ }
275
+ }
276
+ }
277
+
278
+ #[ derive( Clone , Default ) ]
279
+ pub struct CompilerLintFunctions {
280
+ map : FxHashMap < String , String > ,
281
+ }
282
+
283
+ impl CompilerLintFunctions {
284
+ pub fn new ( ) -> Self {
285
+ let mut map = FxHashMap :: default ( ) ;
286
+ map. insert ( "span_lint" . to_string ( ) , "utils::span_lint" . to_string ( ) ) ;
287
+ map. insert ( "struct_span_lint" . to_string ( ) , "utils::span_lint" . to_string ( ) ) ;
288
+ map. insert ( "lint" . to_string ( ) , "utils::span_lint" . to_string ( ) ) ;
289
+ map. insert ( "span_lint_note" . to_string ( ) , "utils::span_note_and_lint" . to_string ( ) ) ;
290
+ map. insert ( "span_lint_help" . to_string ( ) , "utils::span_help_and_lint" . to_string ( ) ) ;
291
+ Self { map }
292
+ }
293
+ }
294
+
295
+ impl LintPass for CompilerLintFunctions {
296
+ fn get_lints ( & self ) -> LintArray {
297
+ lint_array ! ( COMPILER_LINT_FUNCTIONS )
298
+ }
299
+ }
300
+
301
+ impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for CompilerLintFunctions {
302
+ fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , expr : & ' tcx Expr ) {
303
+ if_chain ! {
304
+ if let ExprKind :: MethodCall ( ref path, _, ref args) = expr. node;
305
+ let fn_name = path. ident. as_str( ) . to_string( ) ;
306
+ if let Some ( sugg) = self . map. get( & fn_name) ;
307
+ let ty = walk_ptrs_ty( cx. tables. expr_ty( & args[ 0 ] ) ) ;
308
+ if match_type( cx, ty, & paths:: EARLY_CONTEXT )
309
+ || match_type( cx, ty, & paths:: LATE_CONTEXT ) ;
310
+ then {
311
+ span_help_and_lint(
312
+ cx,
313
+ COMPILER_LINT_FUNCTIONS ,
314
+ path. ident. span,
315
+ "usage of a compiler lint function" ,
316
+ & format!( "Please use the Clippy variant of this function: `{}`" , sugg) ,
317
+ ) ;
318
+ }
245
319
}
246
320
}
247
321
}
0 commit comments