]>
Commit | Line | Data |
---|---|---|
923072b8 | 1 | # Lint Levels |
83c7162d | 2 | |
94222f64 | 3 | In `rustc`, lints are divided into five *levels*: |
83c7162d XL |
4 | |
5 | 1. allow | |
6 | 2. warn | |
94222f64 XL |
7 | 3. force-warn |
8 | 4. deny | |
9 | 5. forbid | |
83c7162d XL |
10 | |
11 | Each lint has a default level (explained in the lint listing later in this | |
12 | chapter), and the compiler has a default warning level. First, let's explain | |
13 | what these levels mean, and then we'll talk about configuration. | |
14 | ||
15 | ## allow | |
16 | ||
17 | These lints exist, but by default, do nothing. For example, consider this | |
18 | source: | |
19 | ||
20 | ```rust | |
21 | pub fn foo() {} | |
22 | ``` | |
23 | ||
24 | Compiling this file produces no warnings: | |
25 | ||
26 | ```bash | |
27 | $ rustc lib.rs --crate-type=lib | |
28 | $ | |
29 | ``` | |
30 | ||
31 | But this code violates the `missing_docs` lint. | |
32 | ||
33 | These lints exist mostly to be manually turned on via configuration, as we'll | |
34 | talk about later in this section. | |
35 | ||
36 | ## warn | |
37 | ||
38 | The 'warn' lint level will produce a warning if you violate the lint. For example, | |
60c5eb7d | 39 | this code runs afoul of the `unused_variables` lint: |
83c7162d XL |
40 | |
41 | ```rust | |
42 | pub fn foo() { | |
43 | let x = 5; | |
44 | } | |
45 | ``` | |
46 | ||
47 | This will produce this warning: | |
48 | ||
b7449926 | 49 | ```bash |
83c7162d XL |
50 | $ rustc lib.rs --crate-type=lib |
51 | warning: unused variable: `x` | |
52 | --> lib.rs:2:9 | |
53 | | | |
54 | 2 | let x = 5; | |
55 | | ^ | |
56 | | | |
416331ca | 57 | = note: `#[warn(unused_variables)]` on by default |
83c7162d XL |
58 | = note: to avoid this warning, consider using `_x` instead |
59 | ``` | |
60 | ||
94222f64 XL |
61 | ## force-warn |
62 | ||
63 | 'force-warn' is a special lint level. It's the same as 'warn' in that a lint | |
64 | at this level will produce a warning, but unlike the 'warn' level, the | |
65 | 'force-warn' level cannot be overridden. If a lint is set to 'force-warn', it | |
66 | is guaranteed to warn: no more, no less. This is true even if the overall lint | |
67 | level is capped via cap-lints. | |
68 | ||
83c7162d XL |
69 | ## deny |
70 | ||
71 | A 'deny' lint produces an error if you violate it. For example, this code | |
72 | runs into the `exceeding_bitshifts` lint. | |
73 | ||
6a06907d | 74 | ```rust,no_run |
83c7162d XL |
75 | fn main() { |
76 | 100u8 << 10; | |
77 | } | |
78 | ``` | |
79 | ||
80 | ```bash | |
b7449926 | 81 | $ rustc main.rs |
83c7162d XL |
82 | error: bitshift exceeds the type's number of bits |
83 | --> main.rs:2:13 | |
84 | | | |
85 | 2 | 100u8 << 10; | |
86 | | ^^^^^^^^^^^ | |
87 | | | |
416331ca | 88 | = note: `#[deny(exceeding_bitshifts)]` on by default |
83c7162d XL |
89 | ``` |
90 | ||
91 | What's the difference between an error from a lint and a regular old error? | |
92 | Lints are configurable via levels, so in a similar way to 'allow' lints, | |
93 | warnings that are 'deny' by default let you allow them. Similarly, you may | |
94 | wish to set up a lint that is `warn` by default to produce an error instead. | |
95 | This lint level gives you that. | |
96 | ||
97 | ## forbid | |
98 | ||
94222f64 XL |
99 | 'forbid' is a special lint level that fills the same role for 'deny' that |
100 | 'force-warn' does for 'warn'. It's the same as 'deny' in that a lint at this | |
101 | level will produce an error, but unlike the 'deny' level, the 'forbid' level | |
102 | can not be overridden to be anything lower than an error. However, lint | |
04454e1e FG |
103 | levels may still be capped with `--cap-lints` (see below) so `rustc --cap-lints warn` |
104 | will make lints set to 'forbid' just warn. | |
83c7162d XL |
105 | |
106 | ## Configuring warning levels | |
107 | ||
108 | Remember our `missing_docs` example from the 'allow' lint level? | |
109 | ||
110 | ```bash | |
111 | $ cat lib.rs | |
112 | pub fn foo() {} | |
113 | $ rustc lib.rs --crate-type=lib | |
114 | $ | |
115 | ``` | |
116 | ||
117 | We can configure this lint to operate at a higher level, both with | |
118 | compiler flags, as well as with an attribute in the source code. | |
119 | ||
120 | You can also "cap" lints so that the compiler can choose to ignore | |
121 | certain lint levels. We'll talk about that last. | |
122 | ||
123 | ### Via compiler flag | |
124 | ||
94222f64 XL |
125 | The `-A`, `-W`, `--force-warn` `-D`, and `-F` flags let you turn one or more lints |
126 | into allowed, warning, force-warn, deny, or forbid levels, like this: | |
83c7162d XL |
127 | |
128 | ```bash | |
129 | $ rustc lib.rs --crate-type=lib -W missing-docs | |
130 | warning: missing documentation for crate | |
131 | --> lib.rs:1:1 | |
132 | | | |
133 | 1 | pub fn foo() {} | |
134 | | ^^^^^^^^^^^^ | |
135 | | | |
136 | = note: requested on the command line with `-W missing-docs` | |
137 | ||
138 | warning: missing documentation for a function | |
139 | --> lib.rs:1:1 | |
140 | | | |
141 | 1 | pub fn foo() {} | |
142 | | ^^^^^^^^^^^^ | |
b7449926 XL |
143 | ``` |
144 | ||
145 | ```bash | |
146 | $ rustc lib.rs --crate-type=lib -D missing-docs | |
83c7162d XL |
147 | error: missing documentation for crate |
148 | --> lib.rs:1:1 | |
149 | | | |
150 | 1 | pub fn foo() {} | |
151 | | ^^^^^^^^^^^^ | |
152 | | | |
153 | = note: requested on the command line with `-D missing-docs` | |
154 | ||
155 | error: missing documentation for a function | |
156 | --> lib.rs:1:1 | |
157 | | | |
158 | 1 | pub fn foo() {} | |
159 | | ^^^^^^^^^^^^ | |
160 | ||
161 | error: aborting due to 2 previous errors | |
162 | ``` | |
163 | ||
164 | You can also pass each flag more than once for changing multiple lints: | |
165 | ||
166 | ```bash | |
b7449926 | 167 | $ rustc lib.rs --crate-type=lib -D missing-docs -D unused-variables |
83c7162d XL |
168 | ``` |
169 | ||
94222f64 | 170 | And of course, you can mix these five flags together: |
83c7162d XL |
171 | |
172 | ```bash | |
b7449926 | 173 | $ rustc lib.rs --crate-type=lib -D missing-docs -A unused-variables |
83c7162d XL |
174 | ``` |
175 | ||
74b04a01 XL |
176 | The order of these command line arguments is taken into account. The following allows the `unused-variables` lint, because it is the last argument for that lint: |
177 | ||
178 | ```bash | |
179 | $ rustc lib.rs --crate-type=lib -D unused-variables -A unused-variables | |
180 | ``` | |
181 | ||
ba9703b0 | 182 | You can make use of this behavior by overriding the level of one specific lint out of a group of lints. The following example denies all the lints in the `unused` group, but explicitly allows the `unused-variables` lint in that group (forbid still trumps everything regardless of ordering): |
74b04a01 XL |
183 | |
184 | ```bash | |
185 | $ rustc lib.rs --crate-type=lib -D unused -A unused-variables | |
186 | ``` | |
187 | ||
94222f64 XL |
188 | Since `force-warn` and `forbid` cannot be overridden, setting |
189 | one of them will prevent any later level for the same lint from | |
190 | taking effect. | |
191 | ||
83c7162d XL |
192 | ### Via an attribute |
193 | ||
194 | You can also modify the lint level with a crate-wide attribute: | |
195 | ||
196 | ```bash | |
b7449926 | 197 | $ cat lib.rs |
83c7162d XL |
198 | #![warn(missing_docs)] |
199 | ||
200 | pub fn foo() {} | |
201 | $ rustc lib.rs --crate-type=lib | |
202 | warning: missing documentation for crate | |
203 | --> lib.rs:1:1 | |
204 | | | |
205 | 1 | / #![warn(missing_docs)] | |
206 | 2 | | | |
207 | 3 | | pub fn foo() {} | |
208 | | |_______________^ | |
209 | | | |
210 | note: lint level defined here | |
211 | --> lib.rs:1:9 | |
212 | | | |
213 | 1 | #![warn(missing_docs)] | |
214 | | ^^^^^^^^^^^^ | |
215 | ||
216 | warning: missing documentation for a function | |
217 | --> lib.rs:3:1 | |
218 | | | |
219 | 3 | pub fn foo() {} | |
220 | | ^^^^^^^^^^^^ | |
221 | ``` | |
222 | ||
94222f64 XL |
223 | `warn`, `allow`, `deny`, and `forbid` all work this way. There is |
224 | no way to set a lint to `force-warn` using an attribute. | |
83c7162d XL |
225 | |
226 | You can also pass in multiple lints per attribute: | |
227 | ||
228 | ```rust | |
229 | #![warn(missing_docs, unused_variables)] | |
230 | ||
231 | pub fn foo() {} | |
232 | ``` | |
233 | ||
234 | And use multiple attributes together: | |
235 | ||
236 | ```rust | |
237 | #![warn(missing_docs)] | |
238 | #![deny(unused_variables)] | |
239 | ||
240 | pub fn foo() {} | |
241 | ``` | |
242 | ||
243 | ### Capping lints | |
244 | ||
245 | `rustc` supports a flag, `--cap-lints LEVEL` that sets the "lint cap level." | |
246 | This is the maximum level for all lints. So for example, if we take our | |
247 | code sample from the "deny" lint level above: | |
248 | ||
6a06907d | 249 | ```rust,no_run |
83c7162d XL |
250 | fn main() { |
251 | 100u8 << 10; | |
252 | } | |
253 | ``` | |
254 | ||
255 | And we compile it, capping lints to warn: | |
256 | ||
257 | ```bash | |
258 | $ rustc lib.rs --cap-lints warn | |
259 | warning: bitshift exceeds the type's number of bits | |
260 | --> lib.rs:2:5 | |
261 | | | |
262 | 2 | 100u8 << 10; | |
263 | | ^^^^^^^^^^^ | |
264 | | | |
416331ca | 265 | = note: `#[warn(exceeding_bitshifts)]` on by default |
83c7162d XL |
266 | |
267 | warning: this expression will panic at run-time | |
268 | --> lib.rs:2:5 | |
269 | | | |
270 | 2 | 100u8 << 10; | |
271 | | ^^^^^^^^^^^ attempt to shift left with overflow | |
272 | ``` | |
273 | ||
274 | It now only warns, rather than errors. We can go further and allow all lints: | |
275 | ||
276 | ```bash | |
277 | $ rustc lib.rs --cap-lints allow | |
278 | $ | |
279 | ``` | |
280 | ||
281 | This feature is used heavily by Cargo; it will pass `--cap-lints allow` when | |
282 | compiling your dependencies, so that if they have any warnings, they do not | |
283 | pollute the output of your build. |