]> git.lizzy.rs Git - rust.git/blob - src/doc/rustc/src/lints/levels.md
Rollup merge of #87910 - iago-lito:mark_unsafe_nonzero_arithmetics_as_const, r=joshtr...
[rust.git] / src / doc / rustc / src / lints / levels.md
1 # Lint levels
2
3 In `rustc`, lints are divided into five *levels*:
4
5 1. allow
6 2. warn
7 3. force-warn
8 4. deny
9 5. forbid
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,
39 this code runs afoul of the `unused_variables` lint:
40
41 ```rust
42 pub fn foo() {
43     let x = 5;
44 }
45 ```
46
47 This will produce this warning:
48
49 ```bash
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   |
57   = note: `#[warn(unused_variables)]` on by default
58   = note: to avoid this warning, consider using `_x` instead
59 ```
60
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
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
74 ```rust,no_run
75 fn main() {
76     100u8 << 10;
77 }
78 ```
79
80 ```bash
81 $ rustc main.rs
82 error: bitshift exceeds the type's number of bits
83  --> main.rs:2:13
84   |
85 2 |     100u8 << 10;
86   |     ^^^^^^^^^^^
87   |
88   = note: `#[deny(exceeding_bitshifts)]` on by default
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
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
103 levels may still be capped with `--cap-lints` (see below) so `rustc --cap-
104 lints warn` will make lints set to 'forbid' just
105 warn.
106
107 ## Configuring warning levels
108
109 Remember our `missing_docs` example from the 'allow' lint level?
110
111 ```bash
112 $ cat lib.rs
113 pub fn foo() {}
114 $ rustc lib.rs --crate-type=lib
115 $
116 ```
117
118 We can configure this lint to operate at a higher level, both with
119 compiler flags, as well as with an attribute in the source code.
120
121 You can also "cap" lints so that the compiler can choose to ignore
122 certain lint levels. We'll talk about that last.
123
124 ### Via compiler flag
125
126 The `-A`, `-W`, `--force-warn` `-D`, and `-F` flags let you turn one or more lints
127 into allowed, warning, force-warn, deny, or forbid levels, like this:
128
129 ```bash
130 $ rustc lib.rs --crate-type=lib -W missing-docs
131 warning: missing documentation for crate
132  --> lib.rs:1:1
133   |
134 1 | pub fn foo() {}
135   | ^^^^^^^^^^^^
136   |
137   = note: requested on the command line with `-W missing-docs`
138
139 warning: missing documentation for a function
140  --> lib.rs:1:1
141   |
142 1 | pub fn foo() {}
143   | ^^^^^^^^^^^^
144 ```
145
146 ```bash
147 $ rustc lib.rs --crate-type=lib -D missing-docs
148 error: missing documentation for crate
149  --> lib.rs:1:1
150   |
151 1 | pub fn foo() {}
152   | ^^^^^^^^^^^^
153   |
154   = note: requested on the command line with `-D missing-docs`
155
156 error: missing documentation for a function
157  --> lib.rs:1:1
158   |
159 1 | pub fn foo() {}
160   | ^^^^^^^^^^^^
161
162 error: aborting due to 2 previous errors
163 ```
164
165 You can also pass each flag more than once for changing multiple lints:
166
167 ```bash
168 $ rustc lib.rs --crate-type=lib -D missing-docs -D unused-variables
169 ```
170
171 And of course, you can mix these five flags together:
172
173 ```bash
174 $ rustc lib.rs --crate-type=lib -D missing-docs -A unused-variables
175 ```
176
177 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:
178
179 ```bash
180 $ rustc lib.rs --crate-type=lib -D unused-variables -A unused-variables
181 ```
182
183 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):
184
185 ```bash
186 $ rustc lib.rs --crate-type=lib -D unused -A unused-variables
187 ```
188
189 Since `force-warn` and `forbid` cannot be overridden, setting
190 one of them will prevent any later level for the same lint from
191 taking effect.
192
193 ### Via an attribute
194
195 You can also modify the lint level with a crate-wide attribute:
196
197 ```bash
198 $ cat lib.rs
199 #![warn(missing_docs)]
200
201 pub fn foo() {}
202 $ rustc lib.rs --crate-type=lib
203 warning: missing documentation for crate
204  --> lib.rs:1:1
205   |
206 1 | / #![warn(missing_docs)]
207 2 | |
208 3 | | pub fn foo() {}
209   | |_______________^
210   |
211 note: lint level defined here
212  --> lib.rs:1:9
213   |
214 1 | #![warn(missing_docs)]
215   |         ^^^^^^^^^^^^
216
217 warning: missing documentation for a function
218  --> lib.rs:3:1
219   |
220 3 | pub fn foo() {}
221   | ^^^^^^^^^^^^
222 ```
223
224 `warn`, `allow`, `deny`, and `forbid` all work this way. There is
225 no way to set a lint to `force-warn` using an attribute.
226
227 You can also pass in multiple lints per attribute:
228
229 ```rust
230 #![warn(missing_docs, unused_variables)]
231
232 pub fn foo() {}
233 ```
234
235 And use multiple attributes together:
236
237 ```rust
238 #![warn(missing_docs)]
239 #![deny(unused_variables)]
240
241 pub fn foo() {}
242 ```
243
244 ### Capping lints
245
246 `rustc` supports a flag, `--cap-lints LEVEL` that sets the "lint cap level."
247 This is the maximum level for all lints. So for example, if we take our
248 code sample from the "deny" lint level above:
249
250 ```rust,no_run
251 fn main() {
252     100u8 << 10;
253 }
254 ```
255
256 And we compile it, capping lints to warn:
257
258 ```bash
259 $ rustc lib.rs --cap-lints warn
260 warning: bitshift exceeds the type's number of bits
261  --> lib.rs:2:5
262   |
263 2 |     100u8 << 10;
264   |     ^^^^^^^^^^^
265   |
266   = note: `#[warn(exceeding_bitshifts)]` on by default
267
268 warning: this expression will panic at run-time
269  --> lib.rs:2:5
270   |
271 2 |     100u8 << 10;
272   |     ^^^^^^^^^^^ attempt to shift left with overflow
273 ```
274
275 It now only warns, rather than errors. We can go further and allow all lints:
276
277 ```bash
278 $ rustc lib.rs --cap-lints allow
279 $
280 ```
281
282 This feature is used heavily by Cargo; it will pass `--cap-lints allow` when
283 compiling your dependencies, so that if they have any warnings, they do not
284 pollute the output of your build.