]>
Commit | Line | Data |
---|---|---|
83c7162d XL |
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_variable` lint: | |
39 | ||
40 | ```rust | |
41 | pub fn foo() { | |
42 | let x = 5; | |
43 | } | |
44 | ``` | |
45 | ||
46 | This will produce this warning: | |
47 | ||
b7449926 | 48 | ```bash |
83c7162d XL |
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,ignore | |
66 | fn main() { | |
67 | 100u8 << 10; | |
68 | } | |
69 | ``` | |
70 | ||
71 | ```bash | |
b7449926 | 72 | $ rustc main.rs |
83c7162d XL |
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 | |
9fa01778 XL |
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. | |
83c7162d XL |
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 | | ^^^^^^^^^^^^ | |
b7449926 XL |
134 | ``` |
135 | ||
136 | ```bash | |
137 | $ rustc lib.rs --crate-type=lib -D missing-docs | |
83c7162d XL |
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 | |
b7449926 | 158 | $ rustc lib.rs --crate-type=lib -D missing-docs -D unused-variables |
83c7162d XL |
159 | ``` |
160 | ||
161 | And of course, you can mix these four flags together: | |
162 | ||
163 | ```bash | |
b7449926 | 164 | $ rustc lib.rs --crate-type=lib -D missing-docs -A unused-variables |
83c7162d XL |
165 | ``` |
166 | ||
167 | ### Via an attribute | |
168 | ||
169 | You can also modify the lint level with a crate-wide attribute: | |
170 | ||
171 | ```bash | |
b7449926 | 172 | $ cat lib.rs |
83c7162d XL |
173 | #![warn(missing_docs)] |
174 | ||
175 | pub fn foo() {} | |
176 | $ rustc lib.rs --crate-type=lib | |
177 | warning: missing documentation for crate | |
178 | --> lib.rs:1:1 | |
179 | | | |
180 | 1 | / #![warn(missing_docs)] | |
181 | 2 | | | |
182 | 3 | | pub fn foo() {} | |
183 | | |_______________^ | |
184 | | | |
185 | note: lint level defined here | |
186 | --> lib.rs:1:9 | |
187 | | | |
188 | 1 | #![warn(missing_docs)] | |
189 | | ^^^^^^^^^^^^ | |
190 | ||
191 | warning: missing documentation for a function | |
192 | --> lib.rs:3:1 | |
193 | | | |
194 | 3 | pub fn foo() {} | |
195 | | ^^^^^^^^^^^^ | |
196 | ``` | |
197 | ||
198 | All four, `warn`, `allow`, `deny`, and `forbid` all work this way. | |
199 | ||
200 | You can also pass in multiple lints per attribute: | |
201 | ||
202 | ```rust | |
203 | #![warn(missing_docs, unused_variables)] | |
204 | ||
205 | pub fn foo() {} | |
206 | ``` | |
207 | ||
208 | And use multiple attributes together: | |
209 | ||
210 | ```rust | |
211 | #![warn(missing_docs)] | |
212 | #![deny(unused_variables)] | |
213 | ||
214 | pub fn foo() {} | |
215 | ``` | |
216 | ||
217 | ### Capping lints | |
218 | ||
219 | `rustc` supports a flag, `--cap-lints LEVEL` that sets the "lint cap level." | |
220 | This is the maximum level for all lints. So for example, if we take our | |
221 | code sample from the "deny" lint level above: | |
222 | ||
223 | ```rust,ignore | |
224 | fn main() { | |
225 | 100u8 << 10; | |
226 | } | |
227 | ``` | |
228 | ||
229 | And we compile it, capping lints to warn: | |
230 | ||
231 | ```bash | |
232 | $ rustc lib.rs --cap-lints warn | |
233 | warning: bitshift exceeds the type's number of bits | |
234 | --> lib.rs:2:5 | |
235 | | | |
236 | 2 | 100u8 << 10; | |
237 | | ^^^^^^^^^^^ | |
238 | | | |
239 | = note: #[warn(exceeding_bitshifts)] on by default | |
240 | ||
241 | warning: this expression will panic at run-time | |
242 | --> lib.rs:2:5 | |
243 | | | |
244 | 2 | 100u8 << 10; | |
245 | | ^^^^^^^^^^^ attempt to shift left with overflow | |
246 | ``` | |
247 | ||
248 | It now only warns, rather than errors. We can go further and allow all lints: | |
249 | ||
250 | ```bash | |
251 | $ rustc lib.rs --cap-lints allow | |
252 | $ | |
253 | ``` | |
254 | ||
255 | This feature is used heavily by Cargo; it will pass `--cap-lints allow` when | |
256 | compiling your dependencies, so that if they have any warnings, they do not | |
257 | pollute the output of your build. |