mirror of
https://github.com/rust-lang/cargo.git
synced 2026-05-06 08:36:38 -04:00
feat(compile): Stabilize build.warnings (#16796)
*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/cargo/pull/16796)* ### What does this PR try to resolve? This allows users to either - hide warnings (#14258) - error on warnings (#8424) `build.warnings` serves a similar purpose as `RUSTFLAGS=-Dwarnings` / `RUSTFLAGS=-Awarnings` but without invalidation caches. `build.warnings = "deny"` will - only errors for lint warnings and not hard warnings - only errors for local warnings and not non-local warnings visible with `--verbose --verbose` - stop the build without `--keep-going` (this matches `RUSTFLAGS=-Dwarnings`) These conditions were not originally met and also came as feedback from rust-lang/rust which has been dogfooding this since the merge of rust-lang/rust#148332. `build.warnings = "allow"` will - only hide lint warnings and not hard warnings - Note: `RUSTFLAGS=-Awarnings` will suppress rustc hard warnings - hide non-local warnings for `--verbose --verbose` - hide the warning summary line (number of warnings per crate) Closes #14802 ### How to test and review this PR? My main concern over this was how the naming scheme would extend to https://github.com/rust-lang/rfcs/pull/3730 but that RFC has not gained much interest `build` seems as good of a home as any.
This commit is contained in:
@@ -913,7 +913,6 @@ unstable_cli_options!(
|
||||
target_applies_to_host: bool = ("Enable the `target-applies-to-host` key in the .cargo/config.toml file"),
|
||||
trim_paths: bool = ("Enable the `trim-paths` option in profiles"),
|
||||
unstable_options: bool = ("Allow the usage of unstable options"),
|
||||
warnings: bool = ("Allow use of the build.warnings config key"),
|
||||
);
|
||||
|
||||
const STABILIZED_COMPILE_PROGRESS: &str = "The progress bar is now always \
|
||||
@@ -1002,6 +1001,8 @@ const STABILIZED_CONFIG_INCLUDE: &str = "The `include` config key is now always
|
||||
|
||||
const STABILIZED_LOCKFILE_PATH: &str = "The `lockfile-path` config key is now always available";
|
||||
|
||||
const STABILIZED_WARNINGS: &str = "The `build.warnings` config key is now always available";
|
||||
|
||||
fn deserialize_comma_separated_list<'de, D>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<Vec<String>>, D::Error>
|
||||
@@ -1391,6 +1392,7 @@ impl CliUnstable {
|
||||
"build-dir" => stabilized_warn(k, "1.91", STABILIZED_BUILD_DIR),
|
||||
"config-include" => stabilized_warn(k, "1.93", STABILIZED_CONFIG_INCLUDE),
|
||||
"lockfile-path" => stabilized_warn(k, "1.97", STABILIZED_LOCKFILE_PATH),
|
||||
"warnings" => stabilized_warn(k, "1.97", STABILIZED_WARNINGS),
|
||||
|
||||
// Unstable features
|
||||
// Sorted alphabetically:
|
||||
@@ -1457,7 +1459,6 @@ impl CliUnstable {
|
||||
"target-applies-to-host" => self.target_applies_to_host = parse_empty(k, v)?,
|
||||
"panic-immediate-abort" => self.panic_immediate_abort = parse_empty(k, v)?,
|
||||
"unstable-options" => self.unstable_options = parse_empty(k, v)?,
|
||||
"warnings" => self.warnings = parse_empty(k, v)?,
|
||||
_ => bail!(
|
||||
"\
|
||||
unknown `-Z` flag specified: {k}\n\n\
|
||||
|
||||
@@ -2147,11 +2147,7 @@ impl GlobalContext {
|
||||
|
||||
/// Get the global [`WarningHandling`] configuration.
|
||||
pub fn warning_handling(&self) -> CargoResult<WarningHandling> {
|
||||
if self.unstable_flags.warnings {
|
||||
Ok(self.build_config()?.warnings.unwrap_or_default())
|
||||
} else {
|
||||
Ok(WarningHandling::default())
|
||||
}
|
||||
Ok(self.build_config()?.warnings.unwrap_or_default())
|
||||
}
|
||||
|
||||
pub fn ws_roots(&self) -> MutexGuard<'_, HashMap<PathBuf, WorkspaceRootConfig>> {
|
||||
|
||||
@@ -204,7 +204,34 @@ This tries to balance thoroughness with turnaround time:
|
||||
- `cargo check` is used as most issues contributors will run into are API availability and not behavior.
|
||||
- Unpublished packages are skipped as this assumes only consumers of the verified project, through a registry, will care about `rust-version`.
|
||||
|
||||
## Checking for warnings
|
||||
|
||||
Customarily, projects want to be "warnings clean" on official branches while being lax for local development.
|
||||
[`build.warnings = "deny"`] can be used to fail a CI job if warnings are present.
|
||||
|
||||
An example CI job to check for warnings using GitHub Actions:
|
||||
```yaml
|
||||
jobs:
|
||||
warnings:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CARGO_BUILD_WARNINGS: deny
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: rustup update stable && rustup default stable
|
||||
- run: rustup component add clippy
|
||||
- run: cargo clippy --all-targets --all-features --keep-going
|
||||
```
|
||||
|
||||
Considerations:
|
||||
- CI can fail due to new toolchain versions because there are limited compatibility guarantees around warnings.
|
||||
Consider pinning the toolchain version with an automated job that creates a PR to upgrade the toolchain on new releases.
|
||||
- Balance between exhaustiveness and turnaround time in selecting the combinations of platforms, features, and package/build-target combinations to check
|
||||
- Some CI systems have direct integration for reporting lints, e.g. using [`clippy-sarif`] with GitHub
|
||||
|
||||
[`build.warnings = "deny"`]: ../reference/config.md#buildwarnings
|
||||
[`cargo add`]: ../commands/cargo-add.md
|
||||
[`cargo install`]: ../commands/cargo-install.md
|
||||
[`clippy-sarif`]: https://crates.io/crates/clippy-sarif
|
||||
[Dependabot]: https://docs.github.com/en/code-security/dependabot/working-with-dependabot
|
||||
[RenovateBot]: https://renovatebot.com/
|
||||
|
||||
@@ -64,6 +64,7 @@ recursive_example = "rr --example recursions"
|
||||
space_example = ["run", "--release", "--", "\"command list\""]
|
||||
|
||||
[build]
|
||||
warnings = "warn" # adjust the effective lint level for warnings
|
||||
jobs = 1 # number of parallel jobs, defaults to # of CPUs
|
||||
rustc = "rustc" # the rust compiler tool
|
||||
rustc-wrapper = "…" # run this wrapper instead of `rustc`
|
||||
@@ -458,6 +459,23 @@ recursive_example = "rr --example recursions"
|
||||
|
||||
The `[build]` table controls build-time operations and compiler settings.
|
||||
|
||||
### `build.warnings`
|
||||
* Type: string
|
||||
* Default: `"warn"`
|
||||
* Environment: `CARGO_BUILD_WARNINGS`
|
||||
|
||||
Adjust the effective level of lint warnings for local packages.
|
||||
Allowed levels are:
|
||||
* `"warn"`: continue to emit the lints as warnings (default).
|
||||
* `"allow"`: hide the lints.
|
||||
* `"deny"`: emit an error for a crate that has lint warnings.
|
||||
Use `--keep-going` to see the lint warnings for all dependent crates.
|
||||
|
||||
Only warnings that are lints (i.e. level is adjustable) are affected,
|
||||
e.g. leaving as-is non-lint warnings or warnings from dependencies visible through `--verbose --verbose`.
|
||||
|
||||
> **MSRV:** Respected as of 1.97.
|
||||
|
||||
#### `build.jobs`
|
||||
* Type: integer or string
|
||||
* Default: number of logical CPUs
|
||||
|
||||
@@ -131,7 +131,6 @@ Each new feature described below should explain how to use it.
|
||||
* [gitoxide](#gitoxide) --- Use `gitoxide` instead of `git2` for a set of operations.
|
||||
* [script](#script) --- Enable support for single-file `.rs` packages.
|
||||
* [native-completions](#native-completions) --- Move cargo shell completions to native completions.
|
||||
* [warnings](#warnings) --- controls warning behavior; options for allowing or denying warnings.
|
||||
* [Package message format](#package-message-format) --- Message format for `cargo package`.
|
||||
* [`fix-edition`](#fix-edition) --- A permanently unstable edition migration helper.
|
||||
* [Plumbing subcommands](https://github.com/crate-ci/cargo-plumbing) --- Low, level commands that act as APIs for Cargo, like `cargo metadata`
|
||||
@@ -1806,28 +1805,6 @@ When in doubt, you can discuss this in [#14520](https://github.com/rust-lang/car
|
||||
- powershell:
|
||||
Add `CARGO_COMPLETE=powershell cargo +nightly | Invoke-Expression` to `$PROFILE`.
|
||||
|
||||
## warnings
|
||||
|
||||
* Original Issue: [#8424](https://github.com/rust-lang/cargo/issues/8424)
|
||||
* Tracking Issue: [#14802](https://github.com/rust-lang/cargo/issues/14802)
|
||||
|
||||
The `-Z warnings` feature enables the `build.warnings` configuration option to control how
|
||||
Cargo handles warnings. If the `-Z warnings` unstable flag is not enabled, then
|
||||
the `build.warnings` config will be ignored.
|
||||
|
||||
This setting currently only applies to rustc warnings. It may apply to additional warnings (such as Cargo lints or Cargo warnings)
|
||||
in the future.
|
||||
|
||||
### `build.warnings`
|
||||
* Type: string
|
||||
* Default: `warn`
|
||||
* Environment: `CARGO_BUILD_WARNINGS`
|
||||
|
||||
Controls how Cargo handles warnings. Allowed values are:
|
||||
* `warn`: warnings are emitted as warnings (default).
|
||||
* `allow`: warnings are hidden.
|
||||
* `deny`: if warnings are emitted, an error will be raised at the end of the current crate and the process. Use `--keep-going` to see all warnings.
|
||||
|
||||
## feature unification
|
||||
|
||||
* RFC: [#3692](https://github.com/rust-lang/rfcs/blob/master/text/3692-feature-unification.md)
|
||||
@@ -2319,3 +2296,7 @@ The `pubtime` index field has been stabilized in Rust 1.94.0.
|
||||
## lockfile-path
|
||||
|
||||
Support for `resolver.lockfile-path` config field has been stabilized in Rust 1.97.0.
|
||||
|
||||
## warnings
|
||||
|
||||
The `build.warnings` config field has been stabilized in Rust 1.97.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<svg width="1255px" height="992px" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="1255px" height="974px" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
.fg { fill: #AAAAAA }
|
||||
.bg { fill: #000000 }
|
||||
@@ -112,17 +112,15 @@
|
||||
</tspan>
|
||||
<tspan x="10px" y="874px"><tspan> -Z unstable-options Allow the usage of unstable options</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="892px"><tspan> -Z warnings Allow use of the build.warnings config key</tspan>
|
||||
<tspan x="10px" y="892px">
|
||||
</tspan>
|
||||
<tspan x="10px" y="910px">
|
||||
<tspan x="10px" y="910px"><tspan>Run with `cargo -Z [FLAG] [COMMAND]`</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="928px"><tspan>Run with `cargo -Z [FLAG] [COMMAND]`</tspan>
|
||||
<tspan x="10px" y="928px">
|
||||
</tspan>
|
||||
<tspan x="10px" y="946px">
|
||||
<tspan x="10px" y="946px"><tspan>See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information about these flags.</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="964px"><tspan>See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information about these flags.</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="982px">
|
||||
<tspan x="10px" y="964px">
|
||||
</tspan>
|
||||
</text>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.7 KiB |
@@ -22,31 +22,11 @@ fn make_project_with_rustc_warning() -> Project {
|
||||
.build()
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn requires_nightly() {
|
||||
// build.warnings has no effect without -Zwarnings.
|
||||
let p = make_project_with_rustc_warning();
|
||||
p.cargo("check")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='deny'")
|
||||
.with_stderr_data(str![[r#"
|
||||
[CHECKING] foo v0.0.1 ([ROOT]/foo)
|
||||
[WARNING] unused variable: `x`
|
||||
...
|
||||
[WARNING] `foo` (bin "foo") generated 1 warning[..]
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
"#]])
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn always_show_error_diags() {
|
||||
let p = make_project_with_rustc_warning();
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.env("RUSTFLAGS", "-Dunused_variables")
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='allow'")
|
||||
.with_stderr_data(str![[r#"
|
||||
@@ -76,8 +56,6 @@ fn clippy() {
|
||||
.build();
|
||||
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='deny'")
|
||||
.env("RUSTC_WORKSPACE_WRAPPER", tools::wrapped_clippy_driver())
|
||||
@@ -97,8 +75,6 @@ fn clippy() {
|
||||
fn config() {
|
||||
let p = make_project_with_rustc_warning();
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.env("CARGO_BUILD_WARNINGS", "deny")
|
||||
.with_stderr_data(str![[r#"
|
||||
[CHECKING] foo v0.0.1 ([ROOT]/foo)
|
||||
@@ -113,8 +89,6 @@ fn config() {
|
||||
|
||||
// CLI has precedence over env
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='warn'")
|
||||
.env("CARGO_BUILD_WARNINGS", "deny")
|
||||
@@ -132,8 +106,6 @@ fn config() {
|
||||
fn unknown_value() {
|
||||
let p = make_project_with_rustc_warning();
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='forbid'")
|
||||
.with_stderr_data(str![[r#"
|
||||
@@ -166,8 +138,6 @@ fn keep_going() {
|
||||
.build();
|
||||
|
||||
p.cargo("build")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='deny'")
|
||||
.with_stderr_data(str![[r#"
|
||||
@@ -184,8 +154,6 @@ fn keep_going() {
|
||||
assert!(!p.bin("foo").is_file());
|
||||
|
||||
p.cargo("build --keep-going")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='deny'")
|
||||
.with_stderr_data(str![[r#"
|
||||
@@ -209,8 +177,6 @@ fn keep_going() {
|
||||
fn rustc_caching_allow_first() {
|
||||
let p = make_project_with_rustc_warning();
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='allow'")
|
||||
.with_stderr_data(str![[r#"
|
||||
@@ -221,8 +187,6 @@ fn rustc_caching_allow_first() {
|
||||
.run();
|
||||
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='deny'")
|
||||
.with_stderr_data(str![[r#"
|
||||
@@ -240,8 +204,6 @@ fn rustc_caching_allow_first() {
|
||||
fn rustc_caching_deny_first() {
|
||||
let p = make_project_with_rustc_warning();
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='deny'")
|
||||
.with_stderr_data(str![[r#"
|
||||
@@ -256,8 +218,6 @@ fn rustc_caching_deny_first() {
|
||||
.run();
|
||||
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='allow'")
|
||||
.with_stderr_data(str![[r#"
|
||||
@@ -328,8 +288,6 @@ fn hard_warning_deny() {
|
||||
|
||||
// Behavior under test
|
||||
p.cargo("rustc")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='deny'")
|
||||
.arg("--")
|
||||
@@ -407,8 +365,6 @@ fn hard_warning_allow() {
|
||||
|
||||
// Behavior under test
|
||||
p.cargo("rustc")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='allow'")
|
||||
.arg("--")
|
||||
@@ -489,8 +445,6 @@ fn cap_lints_deny() {
|
||||
|
||||
// Behavior under test
|
||||
p.cargo("check -vv")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='deny'")
|
||||
.with_stderr_data(str![[r#"
|
||||
@@ -563,8 +517,6 @@ fn cap_lints_allow() {
|
||||
|
||||
// Behavior under test
|
||||
p.cargo("check -vv")
|
||||
.masquerade_as_nightly_cargo(&["warnings"])
|
||||
.arg("-Zwarnings")
|
||||
.arg("--config")
|
||||
.arg("build.warnings='allow'")
|
||||
.with_stderr_data(str![[r#"
|
||||
|
||||
Reference in New Issue
Block a user