Skip to content

Commit de56dff

Browse files
committed
feat: Stabilize build.warnings
This allows users to either - hide warnings (#14258) - error on warnings (#8424) `build.warnings` is setup to mirror the behavior of `RUSTFLAGS=-Dwarnings`, including - 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` 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. Things are a bit different with `RUSTFLAGS=-Awarnings`: - Hard warnings are hidden for rustc but not cargo (rustc seems in the wrong imo) - In particular, we shouldn't mask the edition warning for Cargo Script - both hide the warning summary line (number of warnings per crate) - both hide non-local warnings for `--verbose --verbose` One design constraint we are operating on with this is that changing `build.warnings` should not cause a rebuild, unlike a `RUSTFLAGS` solution. Closes #14802
1 parent 45c2341 commit de56dff

File tree

7 files changed

+59
-86
lines changed

7 files changed

+59
-86
lines changed

src/cargo/core/features.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,6 @@ unstable_cli_options!(
914914
target_applies_to_host: bool = ("Enable the `target-applies-to-host` key in the .cargo/config.toml file"),
915915
trim_paths: bool = ("Enable the `trim-paths` option in profiles"),
916916
unstable_options: bool = ("Allow the usage of unstable options"),
917-
warnings: bool = ("Allow use of the build.warnings config key"),
918917
);
919918

920919
const STABILIZED_COMPILE_PROGRESS: &str = "The progress bar is now always \
@@ -1001,6 +1000,8 @@ const STABILIZED_BUILD_DIR: &str = "build.build-dir is now always enabled.";
10011000

10021001
const STABILIZED_CONFIG_INCLUDE: &str = "The `include` config key is now always available";
10031002

1003+
const STABILIZED_WARNINGS: &str = "The `build.warnings` config key is now always available";
1004+
10041005
fn deserialize_comma_separated_list<'de, D>(
10051006
deserializer: D,
10061007
) -> Result<Option<Vec<String>>, D::Error>
@@ -1389,6 +1390,7 @@ impl CliUnstable {
13891390
"package-workspace" => stabilized_warn(k, "1.89", STABILIZED_PACKAGE_WORKSPACE),
13901391
"build-dir" => stabilized_warn(k, "1.91", STABILIZED_BUILD_DIR),
13911392
"config-include" => stabilized_warn(k, "1.93", STABILIZED_CONFIG_INCLUDE),
1393+
"warnings" => stabilized_warn(k, "1.97", STABILIZED_WARNINGS),
13921394

13931395
// Unstable features
13941396
// Sorted alphabetically:
@@ -1456,7 +1458,6 @@ impl CliUnstable {
14561458
"target-applies-to-host" => self.target_applies_to_host = parse_empty(k, v)?,
14571459
"panic-immediate-abort" => self.panic_immediate_abort = parse_empty(k, v)?,
14581460
"unstable-options" => self.unstable_options = parse_empty(k, v)?,
1459-
"warnings" => self.warnings = parse_empty(k, v)?,
14601461
_ => bail!(
14611462
"\
14621463
unknown `-Z` flag specified: {k}\n\n\

src/cargo/util/context/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,11 +2147,7 @@ impl GlobalContext {
21472147

21482148
/// Get the global [`WarningHandling`] configuration.
21492149
pub fn warning_handling(&self) -> CargoResult<WarningHandling> {
2150-
if self.unstable_flags.warnings {
2151-
Ok(self.build_config()?.warnings.unwrap_or_default())
2152-
} else {
2153-
Ok(WarningHandling::default())
2154-
}
2150+
Ok(self.build_config()?.warnings.unwrap_or_default())
21552151
}
21562152

21572153
pub fn ws_roots(&self) -> MutexGuard<'_, HashMap<PathBuf, WorkspaceRootConfig>> {

src/doc/src/guide/continuous-integration.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,34 @@ This tries to balance thoroughness with turnaround time:
204204
- `cargo check` is used as most issues contributors will run into are API availability and not behavior.
205205
- Unpublished packages are skipped as this assumes only consumers of the verified project, through a registry, will care about `rust-version`.
206206

207+
## Checking for warnings
208+
209+
Customarily, projects want to be "warnings clean" on official branches while being lax for local development.
210+
[`build.warnings = "deny"`] can be used to fail a CI job if warnings are present.
211+
212+
An example CI job to check for warnings using GitHub Actions:
213+
```yaml
214+
jobs:
215+
warnings:
216+
runs-on: ubuntu-latest
217+
env:
218+
CARGO_BUILD_WARNINGS: deny
219+
steps:
220+
- uses: actions/checkout@v4
221+
- run: rustup update stable && rustup default stable
222+
- run: rustup component add clippy
223+
- run: cargo clippy --all-targets --all-features --keep-going
224+
```
225+
226+
Considerations:
227+
- CI can fail due to new toolchain versions because there are limited compatibility guarantees around warnings.
228+
Consider pinning the toolchain version with an automated job that creates a PR to upgrade the toolchain on new releases.
229+
- Balance between exhaustiveness and turnaround time in selecting the combinations of platforms, features, and package/build-target combinations to check
230+
- Some CI systems have direct integration for reporting lints, e.g. using [`clippy-sarif`] with GitHub
231+
232+
[`build.warnings = "deny"`]: ../reference/config.md#buildwarnings
207233
[`cargo add`]: ../commands/cargo-add.md
208234
[`cargo install`]: ../commands/cargo-install.md
235+
[`clippy-sarif`]: https://crates.io/crates/clippy-sarif
209236
[Dependabot]: https://docs.github.com/en/code-security/dependabot/working-with-dependabot
210237
[RenovateBot]: https://renovatebot.com/

src/doc/src/reference/config.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ recursive_example = "rr --example recursions"
6464
space_example = ["run", "--release", "--", "\"command list\""]
6565

6666
[build]
67+
warnings = "warn" # adjust the effective lint level for warnings
6768
jobs = 1 # number of parallel jobs, defaults to # of CPUs
6869
rustc = "rustc" # the rust compiler tool
6970
rustc-wrapper = "" # run this wrapper instead of `rustc`
@@ -457,6 +458,23 @@ recursive_example = "rr --example recursions"
457458

458459
The `[build]` table controls build-time operations and compiler settings.
459460

461+
### `build.warnings`
462+
* Type: string
463+
* Default: `"warn"`
464+
* Environment: `CARGO_BUILD_WARNINGS`
465+
466+
Adjust the effective level for local lint warnings.
467+
Allowed levels are:
468+
* `"warn"`: continue to emit the lints as warnings (default).
469+
* `"allow"`: hide the lints.
470+
* `"deny"`: emit an error for a crate that has lint warnings.
471+
Use `--keep-going` to see the lint warnings for all crates.
472+
473+
Only warnings are affected, which are within the user's control to resolve or adjust the level of are affected,
474+
e.g. leaving as-is non-lint warnings or warnings from dependencies visible through `--verbose --verbose`.
475+
476+
> **MSRV:** Respected as of 1.97.
477+
460478
#### `build.jobs`
461479
* Type: integer or string
462480
* Default: number of logical CPUs

src/doc/src/reference/unstable.md

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ Each new feature described below should explain how to use it.
132132
* [script](#script) --- Enable support for single-file `.rs` packages.
133133
* [lockfile-path](#lockfile-path) --- Allows to specify a path to lockfile other than the default path `<workspace_root>/Cargo.lock`.
134134
* [native-completions](#native-completions) --- Move cargo shell completions to native completions.
135-
* [warnings](#warnings) --- controls warning behavior; options for allowing or denying warnings.
136135
* [Package message format](#package-message-format) --- Message format for `cargo package`.
137136
* [`fix-edition`](#fix-edition) --- A permanently unstable edition migration helper.
138137
* [Plumbing subcommands](https://github.com/crate-ci/cargo-plumbing) --- Low, level commands that act as APIs for Cargo, like `cargo metadata`
@@ -1844,28 +1843,6 @@ When in doubt, you can discuss this in [#14520](https://github.com/rust-lang/car
18441843
- powershell:
18451844
Add `CARGO_COMPLETE=powershell cargo +nightly | Invoke-Expression` to `$PROFILE`.
18461845

1847-
## warnings
1848-
1849-
* Original Issue: [#8424](https://github.com/rust-lang/cargo/issues/8424)
1850-
* Tracking Issue: [#14802](https://github.com/rust-lang/cargo/issues/14802)
1851-
1852-
The `-Z warnings` feature enables the `build.warnings` configuration option to control how
1853-
Cargo handles warnings. If the `-Z warnings` unstable flag is not enabled, then
1854-
the `build.warnings` config will be ignored.
1855-
1856-
This setting currently only applies to rustc warnings. It may apply to additional warnings (such as Cargo lints or Cargo warnings)
1857-
in the future.
1858-
1859-
### `build.warnings`
1860-
* Type: string
1861-
* Default: `warn`
1862-
* Environment: `CARGO_BUILD_WARNINGS`
1863-
1864-
Controls how Cargo handles warnings. Allowed values are:
1865-
* `warn`: warnings are emitted as warnings (default).
1866-
* `allow`: warnings are hidden.
1867-
* `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.
1868-
18691846
## feature unification
18701847

18711848
* RFC: [#3692](https://github.com/rust-lang/rfcs/blob/master/text/3692-feature-unification.md)
@@ -2353,3 +2330,7 @@ See the [`include` config documentation](config.md#include) for more.
23532330
## pubtime
23542331

23552332
The `pubtime` index field has been stabilized in Rust 1.94.0.
2333+
2334+
## warnings
2335+
2336+
The `build.warnings` config field has been stabilized in Rust 1.97.

tests/testsuite/cargo/z_help/stdout.term.svg

Lines changed: 6 additions & 8 deletions
Loading

tests/testsuite/warning_override.rs

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,11 @@ fn make_project_with_rustc_warning() -> Project {
2222
.build()
2323
}
2424

25-
#[cargo_test]
26-
fn requires_nightly() {
27-
// build.warnings has no effect without -Zwarnings.
28-
let p = make_project_with_rustc_warning();
29-
p.cargo("check")
30-
.arg("--config")
31-
.arg("build.warnings='deny'")
32-
.with_stderr_data(str![[r#"
33-
[CHECKING] foo v0.0.1 ([ROOT]/foo)
34-
[WARNING] unused variable: `x`
35-
...
36-
[WARNING] `foo` (bin "foo") generated 1 warning[..]
37-
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
38-
39-
"#]])
40-
.run();
41-
}
42-
4325
#[cargo_test]
4426
fn always_show_error_diags() {
4527
let p = make_project_with_rustc_warning();
4628
p.cargo("check")
47-
.masquerade_as_nightly_cargo(&["warnings"])
4829
.env("RUSTFLAGS", "-Dunused_variables")
49-
.arg("-Zwarnings")
5030
.arg("--config")
5131
.arg("build.warnings='allow'")
5232
.with_stderr_data(str![[r#"
@@ -76,8 +56,6 @@ fn clippy() {
7656
.build();
7757

7858
p.cargo("check")
79-
.masquerade_as_nightly_cargo(&["warnings"])
80-
.arg("-Zwarnings")
8159
.arg("--config")
8260
.arg("build.warnings='deny'")
8361
.env("RUSTC_WORKSPACE_WRAPPER", tools::wrapped_clippy_driver())
@@ -97,8 +75,6 @@ fn clippy() {
9775
fn config() {
9876
let p = make_project_with_rustc_warning();
9977
p.cargo("check")
100-
.masquerade_as_nightly_cargo(&["warnings"])
101-
.arg("-Zwarnings")
10278
.env("CARGO_BUILD_WARNINGS", "deny")
10379
.with_stderr_data(str![[r#"
10480
[CHECKING] foo v0.0.1 ([ROOT]/foo)
@@ -113,8 +89,6 @@ fn config() {
11389

11490
// CLI has precedence over env
11591
p.cargo("check")
116-
.masquerade_as_nightly_cargo(&["warnings"])
117-
.arg("-Zwarnings")
11892
.arg("--config")
11993
.arg("build.warnings='warn'")
12094
.env("CARGO_BUILD_WARNINGS", "deny")
@@ -132,8 +106,6 @@ fn config() {
132106
fn unknown_value() {
133107
let p = make_project_with_rustc_warning();
134108
p.cargo("check")
135-
.masquerade_as_nightly_cargo(&["warnings"])
136-
.arg("-Zwarnings")
137109
.arg("--config")
138110
.arg("build.warnings='forbid'")
139111
.with_stderr_data(str![[r#"
@@ -166,8 +138,6 @@ fn keep_going() {
166138
.build();
167139

168140
p.cargo("build")
169-
.masquerade_as_nightly_cargo(&["warnings"])
170-
.arg("-Zwarnings")
171141
.arg("--config")
172142
.arg("build.warnings='deny'")
173143
.with_stderr_data(str![[r#"
@@ -184,8 +154,6 @@ fn keep_going() {
184154
assert!(!p.bin("foo").is_file());
185155

186156
p.cargo("build --keep-going")
187-
.masquerade_as_nightly_cargo(&["warnings"])
188-
.arg("-Zwarnings")
189157
.arg("--config")
190158
.arg("build.warnings='deny'")
191159
.with_stderr_data(str![[r#"
@@ -209,8 +177,6 @@ fn keep_going() {
209177
fn rustc_caching_allow_first() {
210178
let p = make_project_with_rustc_warning();
211179
p.cargo("check")
212-
.masquerade_as_nightly_cargo(&["warnings"])
213-
.arg("-Zwarnings")
214180
.arg("--config")
215181
.arg("build.warnings='allow'")
216182
.with_stderr_data(str![[r#"
@@ -221,8 +187,6 @@ fn rustc_caching_allow_first() {
221187
.run();
222188

223189
p.cargo("check")
224-
.masquerade_as_nightly_cargo(&["warnings"])
225-
.arg("-Zwarnings")
226190
.arg("--config")
227191
.arg("build.warnings='deny'")
228192
.with_stderr_data(str![[r#"
@@ -240,8 +204,6 @@ fn rustc_caching_allow_first() {
240204
fn rustc_caching_deny_first() {
241205
let p = make_project_with_rustc_warning();
242206
p.cargo("check")
243-
.masquerade_as_nightly_cargo(&["warnings"])
244-
.arg("-Zwarnings")
245207
.arg("--config")
246208
.arg("build.warnings='deny'")
247209
.with_stderr_data(str![[r#"
@@ -256,8 +218,6 @@ fn rustc_caching_deny_first() {
256218
.run();
257219

258220
p.cargo("check")
259-
.masquerade_as_nightly_cargo(&["warnings"])
260-
.arg("-Zwarnings")
261221
.arg("--config")
262222
.arg("build.warnings='allow'")
263223
.with_stderr_data(str![[r#"
@@ -328,8 +288,6 @@ fn hard_warning_deny() {
328288

329289
// Behavior under test
330290
p.cargo("rustc")
331-
.masquerade_as_nightly_cargo(&["warnings"])
332-
.arg("-Zwarnings")
333291
.arg("--config")
334292
.arg("build.warnings='deny'")
335293
.arg("--")
@@ -407,8 +365,6 @@ fn hard_warning_allow() {
407365

408366
// Behavior under test
409367
p.cargo("rustc")
410-
.masquerade_as_nightly_cargo(&["warnings"])
411-
.arg("-Zwarnings")
412368
.arg("--config")
413369
.arg("build.warnings='allow'")
414370
.arg("--")
@@ -489,8 +445,6 @@ fn cap_lints_deny() {
489445

490446
// Behavior under test
491447
p.cargo("check -vv")
492-
.masquerade_as_nightly_cargo(&["warnings"])
493-
.arg("-Zwarnings")
494448
.arg("--config")
495449
.arg("build.warnings='deny'")
496450
.with_stderr_data(str![[r#"
@@ -563,8 +517,6 @@ fn cap_lints_allow() {
563517

564518
// Behavior under test
565519
p.cargo("check -vv")
566-
.masquerade_as_nightly_cargo(&["warnings"])
567-
.arg("-Zwarnings")
568520
.arg("--config")
569521
.arg("build.warnings='allow'")
570522
.with_stderr_data(str![[r#"

0 commit comments

Comments
 (0)