Repository navigation
Add --deny-warnings functionality for all commands. #8424
Description
Tracking issue: #14802
Describe the problem you are trying to solve
I often automate cargo and I typically want any automation to halt when cargo emits warnings. AFAICT the only way to do this is to try to parse the output for the way warnings are typically produced.
(Related issue: there are two categories of warnings which is confusing and needs clarification, which I filed as #8423 .)
Describe the solution you'd like
Add a commandline flag called --deny-warnings and if set, if a warning is encountered, this ensures the process will exit with a non-zero status and that no "non-dry-run" operations proceed. For example, with cargo publish --deny-warnings any of the early local packaging-style lint warnings will cause cargo publish to avoid making any requests to
crates.io.
Notes
I'm not sure about the option name --deny-warnings which I took from the #![deny(warnings)] rust compilation attribute, but I can't think of anything clearer and concise. --treat-warnings-like-errors, --exit-with-error-when-encountering-warnings, --don't-just-warn-me-stop-me!, and --please-save-me-from-myself all are too cumbersome.
Related Tickets
This is related to #3591 because in some way these are opposites (disabling warnings versus escalating them to errors). There might be some common CLI magic that addresses both issues and is clear enough to users.
Even if they use separate cli and/or config specification, if both implemented, they might lead to nonsensical / confusing combinations which a good UX would complain-and-exit about, for example: cargo do-stuff --hide-warnings --deny-warnings or something similar should probably say "I can't tell what you meant to do."
Activity
jrvanwhy commentedon Dec 2, 2020
Commenting to support this feature request.
The project I work on has
-D warningsin its.cargo/config:This works great for CI, where it prevents us from merging code that has warnings. However, it is painful for local development. I frequently add a few lines, run
cargo check, and get errors related to unused variables. I prepend_to variable names and remove it extremely frequently, which is a waste of time.Adding a
--deny-warningsflag to cargo would allow us to use--deny-warningsin our CI infrastructure to block on warnings but still allow iterative code development to proceed without the unnecessary toil caused by-D warnings.CPerezz commentedon Feb 7, 2021
You can already do this in your CI. It's just about setting your ENV variable
RUSTFLAGS= -D warningsand run cargo.Cargo will fetch the ENV variables and pass them to
rustcso that the warnings get denied without needing to add any extra stuff.This would be an example using actions-rs
If you want to treat warnings as errors, or do any fancy stuff, check the docs about lint levels for
rustc: https://doc.rust-lang.org/rustc/lints/levels.htmlI think this issue can be closed considering that
--deny-warningsis already something that can be achieved setting up rustflags.jrvanwhy commentedon Feb 7, 2021
That does not work for projects that need
cargoto pass rust flags configured in.cargo/config. The cargo config documentation says the following about rust flag selection:As an example,
libtock-rsuses.cargo/configto configure relocation. SettingRUSTFLAGSwhile invokingcargocausescargoto ignore this config and create broken binaries.It is possible deny warnings only in CI by including a
cifeature to all our crates and adding#![cfg_attr(feature = "ci", deny(warnings)]to the top of all our crates, but that adds maintenance proportional to the number of crates in the project. Another way to do this is to write code to edit.cargo/configduring CI (we are doing this in libtock-rs#271), but that is hacky and feels fragile.CPerezz commentedon Feb 7, 2021
I understand your point. With multiple crates things get out of control for maintenance.
We're working on an RFC that might make this easier to manage. See: rust-lang/rust-clippy#6625
Although the --deny-warnings would require a bit of design since it can have some edge cases IMO.
wraithan commentedon Jul 22, 2021
Another reason why
RUSTFLAGS="-D warnings"is insufficient as a workaround, even for non-workspace, is that it doesn't account for commands likecargo docwhich is how I stumbled upon this feature request, trying to get warnings when building docs in CI to be bubbled up as failures. I can addgreporrgor w/e to process the output and look for^warning:this way bad links in docs get caught before merged (for example).stephenmartindale commentedon Nov 4, 2021
And yet another reason why
RUSTFLAGSis a terrible, terrible way to control compiler warnings fromrustcis rust-analyzer. If one's build script hacks about withRUSTFLAGS, rust-analyzer has no way of knowing and, because a full recompile gets triggered every single timeRUSTFLAGSchanges (even for seemingly cosmetic things like warning promotion & suppression), the result can be a complete nightmare as rust-analyzer and the build scripts fight overtarget.Hmm. Now that I write that, I realise that promoting warnings to build-failing errors actually is not a cosmetic thing and, perhaps, it actually should force a full recompile, following the same arguments behind
cargo package's full recompile, because warnings-as-errors is typically something that gets employed in CI and for actual release builds.Anders429 commentedon Mar 17, 2022
For the
cargo docuse case specifically, it seems that usingRUSTDOCFLAGSinstead ofRUSTFLAGSgets the job done. For example, runningRUSTDOCFLAGS='-D warnings' cargo docpromotes all warnings to failures.veber-alex commentedon Aug 8, 2023
Is there anything new regarding this issue?
I want to run cargo check with deny warnings as a precommit hook but the only way is to set RUSTFLAGS which causes a recompile of the crate and all the dependencies.
epage commentedon Aug 8, 2023
If its not in this issue, likely not. The closest related work is #12115 which removes some reliance on RUSTFLAGS for dealing with warnings but not in this case.
The hard thing here is that technically your dependencies are reporting warnings and deny-warnings could affect them, so we'd need to recompile to verify that. However, with caplints, most warnings from dependencies are dropped and with our caching of warnings between runs, rebuilds aren't needed.
The challenge with RUSTFLAGS is that its opaque to us (and should remain so) and that it applies to all packages when you only care about workspace members. #8716 at least partially improves the RUSTFLAGS situation because we would generate separate files for each RUSTFLAGS, rather than overwriting, so a full rebuild would happen once and then we'd rebuild on top of that.
veber-alex commentedon Aug 8, 2023
I don't think using RUSTFLAGS here is the correct solution, clippy has the option to control the lints directly using
cargo clippy -- -Dwarnings.You can also do this with
cargo rustc --lib -- -Dwarningsbut that runs only for one target.I think cargo check and build need something like this.
Fix clippy warnings and enforce -Dwarnings (#224)
epage commentedon Sep 26, 2023
Been thinking about this more in the context of "how do we rely on RUSTFLAGS less?"
In a case like this, a
cargo check -- -Dwarningscan cause things to rebuild because you are passing in a RUSTFLAGS and cargo has no idea what it will do.What if we added a flag
--warnings <deny|allow>that was completely processed within cargo, relying on the cached output from rustc that cargo replays when a crate doesn't need rebuilding (#6933)noraa-july-stoke commentedon Sep 26, 2023
That would be really useful for some of my use cases so I can just focus on looking at critical errors when I need to.
29 remaining items
Fix rustdoc warnings and add CI
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat: Stabilize `build.warnings`
feat(compile): Stabilize `build.warnings` (rust-lang#16796)