@@ -9,11 +9,8 @@ Note that we will not go into concrete implementation of a lint logic in this
9
9
chapter. We will go into details in later chapters as well as in two examples
10
10
of real Clippy lints.
11
11
12
- In this chapter, we'll see an example of an imaginary ` LateLintPass ` lint named ` bar_expressions ` , that checks for
13
- expresions named ` bar ` .
14
-
15
- To emit a lint with ` LateLintPass ` , we must implement it for the lint that we have
16
- declared. Take a look at the [ LateLintPass] [ late_lint_pass ] documentation, which
12
+ To emit a lint, we must implement a pass (see [ Lint Passes] ( lint_passes.md ) ) for the lint that we have
13
+ declared. In this example we'll implement a "late" lint, so take a look at the [ LateLintPass] [ late_lint_pass ] documentation, which
17
14
provides an abundance of methods that we can implement for our lint.
18
15
19
16
``` rust
@@ -23,48 +20,39 @@ pub trait LateLintPass<'tcx>: LintPass {
23
20
```
24
21
25
22
By far the most common method used for Clippy lints is [ ` check_expr ` method] [ late_check_expr ] ,
26
- this is likely because Rust is an expression language and, more often than not,
23
+ this is because Rust is an expression language and, more often than not,
27
24
the lint we want to work on must examine expressions.
28
25
29
26
> _ Note:_ If you don't fully understand what expressions are in Rust,
30
27
> take a look at the official documentation on [ expressions] [ rust_expressions ]
31
28
32
29
Other common ones include the [ ` check_fn ` method] [ late_check_fn ] and the
33
- [ ` check_item ` method] [ late_check_item ] . We choose to implement whichever trait
34
- method based on what we need for the lint at hand.
35
-
36
- ### Implement Trait Method
37
-
38
- Assume that we have added and defined a ` bar_expressions ` lint, we could write
39
- down a skeleton for this lint as the following:
40
-
41
- ``` rust
42
- impl <'tcx > LateLintPass <'tcx > for BarExpressions {
43
- fn check_expr (& mut self , cx : & LateContext <'tcx >, expr : & 'tcx Expr <'_ >) {}
44
- }
45
- ```
30
+ [ ` check_item ` method] [ late_check_item ] .
46
31
47
32
### Emitting a lint
48
33
49
34
Inside the trait method that we implement, we can write down the lint logic
50
- and the emit the lint with suggestions.
35
+ and emit the lint with suggestions.
51
36
52
37
Clippy's [ diagnostics] provides quite a few diagnostic functions that we can
53
38
use to emit lints. Take a look at the documentation to pick one that suits
54
39
your lint's needs the best. Some common ones you will encounter in the Clippy
55
40
repository includes:
56
41
57
- - [ span_lint_and_help] : emits a lint and provides a helpful message
58
- - [ span_lint_and_sugg] : emits a lint and provides a suggestion to fix the code
42
+ - [ ` span_lint ` ] : Emits a lint without providing any other information
43
+ - [ ` span_lint_and_note ` ] : Emits a lint and adds a note
44
+ - [ ` span_lint_and_help ` ] : Emits a lint and provides a helpful message
45
+ - [ ` span_lint_and_sugg ` ] : Emits a lint and provides a suggestion to fix the code
46
+ - [ ` span_lint_and_then ` ] : Like ` span_lint ` , but allows for a lot of output customization.
59
47
60
48
``` rust
61
- impl <'tcx > LateLintPass <'tcx > for BarExpressions {
49
+ impl <'tcx > LateLintPass <'tcx > for LintName {
62
50
fn check_expr (& mut self , cx : & LateContext <'tcx >, expr : & 'tcx Expr <'_ >) {
63
- // Imagine that `some_bar_expr_logic ` checks for requirements for emitting the lint
64
- if some_bar_expr_logic (expr ) {
51
+ // Imagine that `some_lint_expr_logic ` checks for requirements for emitting the lint
52
+ if some_lint_expr_logic (expr ) {
65
53
span_lint_and_help (
66
54
cx , // < The context
67
- FOO_FUNCTIONS , // < The name of the lint in ALL CAPS
55
+ LINT_NAME , // < The name of the lint in ALL CAPS
68
56
expr . span, // < The span to lint
69
57
" message on why the lint is emitted" ,
70
58
None , // < An optional help span (to highlight something in the lint)
@@ -75,17 +63,16 @@ impl<'tcx> LateLintPass<'tcx> for BarExpressions {
75
63
}
76
64
```
77
65
78
- > Note: According to [ the rustc-dev-guide] , the message should be matter of fact and avoid
79
- > capitalization and periods, unless multiple sentences are needed. When code or
80
- > an identifier must appear in a message or label, it should be surrounded with
81
- > single grave accents (\` ).
66
+ > Note: The message should be matter of fact and avoid
67
+ > capitalization and punctuation. If multiple sentences are needed, the messages should probably be split up into an
68
+ > error + a help / note / suggestion message.
82
69
83
70
## Suggestions: Automatic fixes
84
71
85
- Some lints know what to change in order to fix the lint. A real world example, the lint
86
- [ ` range_plus ` ] [ range_plus_one ] lints for ranges where the user wrote ` x..y + 1 ` instead of using an
87
- [ inclusive range] [ inclusive_range ] (` x..=1 ` ). The fix to this lint would be just changing your ` x..y + 1 ` expression
88
- to ` x..=y ` , ** this is where suggestions come in** .
72
+ Some lints know what to change in order to fix the code. For example, the lint
73
+ [ ` range_plus ` ] [ range_plus_one ] warns for ranges where the user wrote ` x..y + 1 ` instead of using an
74
+ [ inclusive range] [ inclusive_range ] (` x..=1 ` ). The fix to this code would be changing the ` x..y + 1 ` expression
75
+ to ` x..=y ` . ** This is where suggestions come in** .
89
76
90
77
A suggestion is a change that the lint provides to fix the issue it is linting.
91
78
The output looks something like this (from the example earlier):
@@ -102,21 +89,21 @@ LL | for _ in 1..1 + 1 {}
102
89
[ Applicability] [ applicability ] .
103
90
104
91
Applicability indicates confidence in the correctness of the suggestion, some are always right
105
- (` Applicability::MachineApplicable ` ), but we use ` Applicability::MaybeIncorrect ` and other when talking about a lint
92
+ (` Applicability::MachineApplicable ` ), but we use ` Applicability::MaybeIncorrect ` and others when talking about a lint
106
93
that may be incorrect.
107
94
108
95
---
109
96
110
- The same lint ( ` foo_functions ` ) but that emits a suggestion would be something like this:
97
+ The same lint ` LINT_NAME ` but that emits a suggestion would be something like this:
111
98
112
99
``` rust
113
- impl <'tcx > LateLintPass <'tcx > for BarExpressions {
100
+ impl <'tcx > LateLintPass <'tcx > for LintName {
114
101
fn check_expr (& mut self , cx : & LateContext <'tcx >, expr : & 'tcx Expr <'_ >) {
115
- // Imagine that `some_bar_expr_logic ` checks for requirements for emitting the lint
116
- if some_bar_expr_logic (expr ) {
102
+ // Imagine that `some_lint_expr_logic ` checks for requirements for emitting the lint
103
+ if some_lint_expr_logic (expr ) {
117
104
span_lint_and_sugg ( // < Note this change
118
105
cx ,
119
- BAR_EXPRESSIONS ,
106
+ LINT_NAME ,
120
107
span ,
121
108
" message on why the lint is emitted" ,
122
109
" use" ,
@@ -171,8 +158,8 @@ error: constant division of 0.0 with 0.0 will always result in NaN
171
158
172
159
---
173
160
174
- Suggestions are the most helpful, they are direct changes to the source code in order to fix the error. The magic
175
- in suggestions is that tools like rustfix can detect them and automatically fix your code.
161
+ Suggestions are the most helpful, they are changes to the source code to fix the error. The magic
162
+ in suggestions is that tools like ` rustfix ` can detect them and automatically fix your code.
176
163
177
164
Example:
178
165
@@ -208,8 +195,11 @@ cover in the next chapters.
208
195
[ late_check_item ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_item
209
196
[ late_lint_pass ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html
210
197
[ rust_expressions ] : https://doc.rust-lang.org/reference/expressions.html
211
- [ span_lint_and_help ] : https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_help.html
212
- [ span_lint_and_sugg ] : https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html
198
+ [ `span_lint` ] : https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint.html
199
+ [ `span_lint_and_note` ] : https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_note.html
200
+ [ `span_lint_and_help` ] : https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_help.html
201
+ [ `span_lint_and_sugg` ] : https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html
202
+ [ `span_lint_and_then` ] : https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_then.html
213
203
[ the rustc-dev-guide ] : https://rustc-dev-guide.rust-lang.org/diagnostics.html
214
204
[ range_plus_one ] : https://rust-lang.github.io/rust-clippy/master/index.html#range_plus_one
215
205
[ inclusive_range ] : https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html
0 commit comments