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