Skip to content

Commit fc2c6ce

Browse files
committed
Doc: clarify priority of lint level sources
This updates the rustc book to clearly document how conflicting lint configurations are resolved across different sources, including command-line flags, crate-level attributes, in-line attributes, and `--cap-lints`. It also explains the special behavior of `forbid` and `force_warn`.
1 parent 449c801 commit fc2c6ce

File tree

1 file changed

+102
-1
lines changed

1 file changed

+102
-1
lines changed

src/doc/rustc/src/lints/levels.md

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,105 @@ $
330330
331331
This feature is used heavily by Cargo; it will pass `--cap-lints allow` when
332332
compiling your dependencies, so that if they have any warnings, they do not
333-
pollute the output of your build.
333+
pollute the output of your build. However, note that `--cap-lints allow` does **not** override lints marked as `force-warn`.
334+
335+
## Priority of lint level sources
336+
337+
Rust allows setting lint levels (`allow`, `warn`, `deny`, `forbid`, `force-warn`) through various sources:
338+
339+
- **Attributes**: `#[allow(...)]`, `#![deny(...)]`, etc.
340+
- **Command-line options**: `--cap-lints`, `--force-warn`, `-A`, `-W`, `-D`, `-F`
341+
342+
Here’s how these different lint controls interact:
343+
344+
1. [`--force-warn`](#force-warn) forces a lint to warning level, and takes precedence over attributes and all other CLI flags.
345+
346+
```rust,compile_fail
347+
#[forbid(unused_variables)]
348+
fn main() {
349+
let x = 42;
350+
}
351+
```
352+
353+
Compiled with:
354+
355+
```bash
356+
$ rustc --force-warn unused_variables lib.rs
357+
warning: unused variable: `x`
358+
--> lib.rs:3:9
359+
|
360+
3 | let x = 42;
361+
| ^ help: if this is intentional, prefix it with an underscore: `_x`
362+
|
363+
= note: requested on the command line with `--force-warn unused-variables`
364+
365+
warning: 1 warning emitted
366+
```
367+
368+
2. [`--cap-lints`](#capping-lints) sets the maximum level of a lint, and takes precedence over attributes and the `-D`, `-W`, `-F` CLI flags.
369+
370+
```rust,compile_fail
371+
#[deny(unused_variables)]
372+
fn main() {
373+
let x = 42;
374+
}
375+
```
376+
377+
Compiled with:
378+
379+
```bash
380+
$ rustc --cap-lints=warn lib.rs
381+
warning: unused variable: `x`
382+
--> test1.rs:3:9
383+
|
384+
3 | let x = 42;
385+
| ^ help: if this is intentional, prefix it with an underscore: `_x`
386+
|
387+
note: the lint level is defined here
388+
--> test1.rs:1:8
389+
|
390+
1 | #[deny(unused_variables)]
391+
| ^^^^^^^^^^^^^^^^
392+
393+
warning: 1 warning emitted
394+
```
395+
396+
3. [CLI level flags](#via-compiler-flag) take precedence over attributes.
397+
398+
The order of the flags matter; flags on the right take precedence over earlier flags.
399+
400+
```rust
401+
fn main() {
402+
let x = 42;
403+
}
404+
```
405+
406+
Compiled with:
407+
408+
```bash
409+
$ rustc -A unused_variables -D unused_variables lib.rs
410+
error: unused variable: `x`
411+
--> test1.rs:2:9
412+
|
413+
2 | let x = 42;
414+
| ^ help: if this is intentional, prefix it with an underscore: `_x`
415+
|
416+
= note: requested on the command line with `-D unused-variables`
417+
418+
error: aborting due to 1 previous error
419+
```
420+
421+
4. Within the source, [attributes](#via-an-attribute) at a lower-level in the syntax tree take precedence over attributes at a higher level, or from a previous attribute on the same entity as listed in left-to-right source order.
422+
423+
```rust
424+
#![deny(unused_variables)]
425+
426+
#[allow(unused_variables)]
427+
fn main() {
428+
let x = 42; // Allow wins
429+
}
430+
```
431+
432+
- The exception is once a lint is set to "forbid", it is an error to try to change its level except for `deny`, which is allowed inside a forbid context, but is ignored.
433+
434+
In terms of priority, [lint groups](groups.md) are treated as-if they are expanded to a list of all of the lints they contain. The exception is the `warnings` group which ignores attribute and CLI order and applies to all lints that would otherwise warn within the entity.

0 commit comments

Comments
 (0)