@@ -107,13 +107,15 @@ our lint, we need to commit the generated `.stderr` files, too.
107
107
108
108
If the lint you are working on is making use of structured suggestions, the
109
109
test file should include a ` // run-rustfix ` comment at the top. This will
110
- additionally run [ rustfix] ( https://github.com/rust-lang-nursery/rustfix ) for
111
- that test. Rustfix will apply the suggestions from the lint to the code of the
112
- test file and compare that to the contents of a ` .fixed ` file.
110
+ additionally run [ rustfix] for that test. Rustfix will apply the suggestions
111
+ from the lint to the code of the test file and compare that to the contents of
112
+ a ` .fixed ` file.
113
113
114
114
Use ` tests/ui/update-all-references.sh ` to automatically generate the
115
115
` .fixed ` file after running the tests.
116
116
117
+ [ rustfix ] : https://github.com/rust-lang/rustfix
118
+
117
119
## Edition 2018 tests
118
120
119
121
Some features require the 2018 edition to work (e.g. ` async_await ` ), but
@@ -167,10 +169,10 @@ declare_clippy_lint! {
167
169
* The section of lines prefixed with ` /// ` constitutes the lint documentation
168
170
section. This is the default documentation style and will be displayed
169
171
[ like this] [ example_lint_page ] .
170
- * ` FOO_FUNCTIONS ` is the name of our lint. Be sure to follow the [ lint naming
171
- guidelines] [ lint_naming ] here when naming your lint. In short, the name should
172
- state the thing that is being checked for and read well when used with
173
- ` allow ` /` warn ` /` deny ` .
172
+ * ` FOO_FUNCTIONS ` is the name of our lint. Be sure to follow the
173
+ [ lint naming guidelines] [ lint_naming ] here when naming your lint.
174
+ In short, the name should state the thing that is being checked for and
175
+ read well when used with ` allow ` /` warn ` /` deny ` .
174
176
* ` pedantic ` sets the lint level to ` Allow ` .
175
177
The exact mapping can be found [ here] [ category_level_mapping ]
176
178
* The last part should be a text that explains what exactly is wrong with the
@@ -200,7 +202,10 @@ automate everything. We will have to register our lint pass manually in the
200
202
store . register_early_pass (|| box foo_functions :: FooFunctions );
201
203
```
202
204
203
- [ example lint page ] : https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
205
+ [ declare_clippy_lint ] : https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L60
206
+ [ example_lint_page ] : https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
207
+ [ lint_naming ] : https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
208
+ [ category_level_mapping ] : https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L110
204
209
205
210
## Lint passes
206
211
@@ -220,6 +225,9 @@ Since we don't need type information for checking the function name, we used
220
225
` --pass=early ` when running the new lint automation and all the imports were
221
226
added accordingly.
222
227
228
+ [ early_lint_pass ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html
229
+ [ late_lint_pass ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html
230
+
223
231
## Emitting a lint
224
232
225
233
With UI tests and the lint declaration in place, we can start working on the
@@ -265,13 +273,16 @@ impl EarlyLintPass for FooFunctions {
265
273
266
274
Running our UI test should now produce output that contains the lint message.
267
275
276
+ [ check_fn ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html#method.check_fn
277
+ [ diagnostics ] : https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/utils/diagnostics.rs
278
+
268
279
## Adding the lint logic
269
280
270
281
Writing the logic for your lint will most likely be different from our example,
271
282
so this section is kept rather short.
272
283
273
284
Using the [ ` check_fn ` ] [ check_fn ] method gives us access to [ ` FnKind ` ] [ fn_kind ]
274
- that has the ` FnKind::Fn ` variant. It provides access to the name of the
285
+ that has the [ ` FnKind::Fn ` ] variant. It provides access to the name of the
275
286
function/method via an [ ` Ident ` ] [ ident ] .
276
287
277
288
With that we can expand our ` check_fn ` method to:
@@ -323,6 +334,10 @@ implementation is not violating any Clippy lints itself.
323
334
That should be it for the lint implementation. Running ` cargo test ` should now
324
335
pass.
325
336
337
+ [ fn_kind ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/visit/enum.FnKind.html
338
+ [ `FnKind::Fn` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/visit/enum.FnKind.html#variant.Fn
339
+ [ ident ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Ident.html
340
+
326
341
## Author lint
327
342
328
343
If you have trouble implementing your lint, there is also the internal ` author `
@@ -340,6 +355,8 @@ see the generated code in the output below.
340
355
If the command was executed successfully, you can copy the code over to where
341
356
you are implementing your lint.
342
357
358
+ [ author_example ] : https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=9a12cb60e5c6ad4e3003ac6d5e63cf55
359
+
343
360
## Documentation
344
361
345
362
The final thing before submitting our PR is to add some documentation to our
@@ -373,11 +390,13 @@ declare_clippy_lint! {
373
390
Once your lint is merged, this documentation will show up in the [ lint
374
391
list] [ lint_list ] .
375
392
393
+ [ lint_list ] : https://rust-lang.github.io/rust-clippy/master/index.html
394
+
376
395
## Running rustfmt
377
396
378
- [ Rustfmt] ( https://github.com/rust-lang/rustfmt ) is a tool for formatting Rust
379
- code according to style guidelines. Your code has to be formatted by ` rustfmt `
380
- before a PR can be merged. Clippy uses nightly ` rustfmt ` in the CI.
397
+ [ Rustfmt] is a tool for formatting Rust code according to style guidelines.
398
+ Your code has to be formatted by ` rustfmt ` before a PR can be merged.
399
+ Clippy uses nightly ` rustfmt ` in the CI.
381
400
382
401
It can be installed via ` rustup ` :
383
402
@@ -388,12 +407,16 @@ rustup component add rustfmt --toolchain=nightly
388
407
Use ` cargo dev fmt ` to format the whole codebase. Make sure that ` rustfmt ` is
389
408
installed for the nightly toolchain.
390
409
410
+ [ Rustfmt ] : https://github.com/rust-lang/rustfmt
411
+
391
412
## Debugging
392
413
393
414
If you want to debug parts of your lint implementation, you can use the [ ` dbg! ` ]
394
415
macro anywhere in your code. Running the tests should then include the debug
395
416
output in the ` stdout ` part.
396
417
418
+ [ `dbg!` ] : https://doc.rust-lang.org/std/macro.dbg.html
419
+
397
420
## PR Checklist
398
421
399
422
Before submitting your PR make sure you followed all of the basic requirements:
@@ -437,26 +460,14 @@ documentation currently. This is unfortunate, but in most cases you can probably
437
460
get away with copying things from existing similar lints. If you are stuck,
438
461
don't hesitate to ask on [ Discord] or in the issue/PR.
439
462
440
- [ lint_list ] : https://rust-lang.github.io/rust-clippy/master/index.html
441
- [ lint_naming ] : https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
442
- [ category_level_mapping ] : https://github.com/rust-lang/rust-clippy/blob/bd23cb89ec0ea63403a17d3fc5e50c88e38dd54f/clippy_lints/src/lib.rs#L43
443
- [ declare_clippy_lint ] : https://github.com/rust-lang/rust-clippy/blob/a71acac1da7eaf667ab90a1d65d10e5cc4b80191/clippy_lints/src/lib.rs#L39
444
- [ check_fn ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html#method.check_fn
445
- [ early_lint_pass ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html
446
- [ late_lint_pass ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html
447
- [ fn_kind ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/visit/enum.FnKind.html
448
- [ diagnostics ] : https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/utils/diagnostics.rs
449
463
[ utils ] : https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/utils/mod.rs
450
- [ ident ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Ident.html
451
- [ span ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html
452
- [ applicability ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
453
464
[ if_chain ] : https://docs.rs/if_chain/*/if_chain/
454
- [ ty ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/sty/index.html
455
- [ ast ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/index.html
456
465
[ from_expansion ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
457
466
[ in_external_macro ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/fn.in_external_macro.html
458
- [ author_example ] : https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=9a12cb60e5c6ad4e3003ac6d5e63cf55
467
+ [ span ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html
468
+ [ applicability ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
459
469
[ rustc-dev-guide ] : https://rustc-dev-guide.rust-lang.org/
460
470
[ nightly_docs ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
471
+ [ ast ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/index.html
472
+ [ ty ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/sty/index.html
461
473
[ Discord ] : https://discord.gg/rust-lang
462
- [ `dbg`! ] : https://doc.rust-lang.org/std/macro.dbg.html
0 commit comments