- Feature Name: N/A
- Start Date: 2015-07-07
- RFC PR: rust-lang/rfcs#1193
- Rust Issue: rust-lang/rust#27259
Add a new flag to the compiler,
--cap-lints, which set the maximum possible
lint level for the entire crate (and cannot be overridden). Cargo will then pass
--cap-lints allow to all upstream dependencies when compiling code.
Note: this RFC represents issue #1029
Currently any modification to a lint in the compiler is strictly speaking a
breaking change. All crates are free to place
#![deny(warnings)] at the top of
their crate, turning any new warnings into compilation errors. This means that
if a future version of Rust starts to emit new warnings it may fail to compile
some previously written code (a breaking change).
We would very much like to be able to modify lints, however. For example
rust-lang/rust#26473 updated the
missing_docs lint to also look for
missing documentation on
const items. This ended up breaking some
crates in the ecosystem due to their usage of
The mechanism proposed in this RFC is aimed at providing a method to compile upstream dependencies in a way such that they are resilient to changes in the behavior of the standard lints in the compiler. A new lint warning or error will never represent a memory safety issue (otherwise it'd be a real error) so it should be safe to ignore any new instances of a warning that didn't show up before.
There are two primary changes propsed by this RFC, the first of which is a new flag to the compiler:
--cap-lints LEVEL Set the maximum lint level for this compilation, cannot be overridden by other flags or attributes.
For example when
--cap-lints allow is passed, all instances of
#[forbid] are ignored. If, however
--cap-lints warn is passed
forbid directives are ignored.
The acceptable values for
LEVEL will be
The second change proposed is to have Cargo pass
--cap-lints allow to all
upstream dependencies. Cargo currently passes
-A warnings to all upstream
dependencies (allow all warnings by default), so this would just be guaranteeing
that no lints could be fired for upstream dependencies.
With these two pieces combined together it is now possible to modify lints in the compiler in a backwards compatible fashion. Modifications to existing lints to emit new warnings will not get triggered, and new lints will also be entirely suppressed only for upstream dependencies.
This flag would be first non-1.0 flag that Cargo would be passing to the
compiler. This means that Cargo can no longer drive a 1.0 compiler, but only a
1.N+ compiler which has the
--cap-lints flag. To handle this discrepancy Cargo
will detect whether
--cap-lints is a valid flag to the compiler.
Cargo already runs
rustc -vV to learn about the compiler (e.g. a "unique
string" that's opaque to Cargo) and it will instead start passing
rustc -vV --cap-lints allow to the compiler instead. This will allow Cargo to
simultaneously detect whether the flag is valid and learning about the version
string. If this command fails and
rustc -vV succeeds then Cargo will fall back
to the old behavior of passing
This RFC adds surface area to the command line of the compiler with a relatively
--cap-lints. The option will almost never be passed by anything
other than Cargo, so having it show up here is a little unfortunate.
Some crates may inadvertently rely on memory safety through lints, or otherwise very much not want lints to be turned off. For example if modifications to a new lint to generate more warnings caused an upstream dependency to fail to compile, it could represent a serious bug indicating the dependency needs to be updated. This system would paper over this issue by forcing compilation to succeed. This use case seems relatively rare, however, and lints are also perhaps not the best method to ensure the safety of a crate.
Cargo may one day grow configuration to not pass this flag by default (e.g. go
back to passing
-Awarnings by default), which is yet again more expansion of
API surface area.
- Modifications to lints or additions to lints could be considered backwards-incompatible changes.
- The meaning of the
-Aflag could be reinterpreted as "this cannot be overridden"
- A new "meta lint" could be introduced to represent the maximum cap, for
-A everything. This is semantically different enough from
-A foothat it seems worth having a new flag.