From 2c48b10ef090d70508f6bce2c8da8f1bb6cff11d Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 22 May 2023 13:44:56 -0500 Subject: [PATCH 1/2] test(lints): Remove unused cargo-features --- tests/testsuite/lints.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testsuite/lints.rs b/tests/testsuite/lints.rs index b2aa0eee7c7..cc834081eb7 100644 --- a/tests/testsuite/lints.rs +++ b/tests/testsuite/lints.rs @@ -504,7 +504,7 @@ fn build_rustflags_has_precedence() { .file( "Cargo.toml", r#" - cargo-features = ["lints", "profile-rustflags"] + cargo-features = ["lints"] [package] name = "foo" @@ -533,7 +533,7 @@ pub fn foo(num: i32) -> u32 { foo.cargo("check") .arg("-v") // Show order of rustflags on failure - .masquerade_as_nightly_cargo(&["lints", "profile-rustflags"]) + .masquerade_as_nightly_cargo(&["lints"]) .run(); } From 08fdd86d840f99db5f15ea4de9021c404581353e Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 19 May 2023 13:32:09 -0500 Subject: [PATCH 2/2] fix(lints): Switch to `-Zlints` so stable projects can experiment In rust-lang/cargo#12115, we explored how we can let stable projects experiment with `[lints]` to provide feedback. What we settled on is switching from the `cargo-features` manifest key to the `-Z` flag as `cargo-features` always requires nightly while `-Z` only requires it when being passed in. This means a project can have a `[lints]` table and have CI / contributors run `cargo +nightly check -Zlints` when they care about warnings. --- src/cargo/core/features.rs | 5 +-- src/cargo/util/toml/mod.rs | 44 +++++++------------ src/doc/src/reference/unstable.md | 6 +-- tests/testsuite/lints.rs | 73 ++++++++++--------------------- 4 files changed, 43 insertions(+), 85 deletions(-) diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 04e2ca87741..d56054a0a73 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -483,9 +483,6 @@ features! { // Allow specifying rustflags directly in a profile (stable, workspace_inheritance, "1.64", "reference/unstable.html#workspace-inheritance"), - - // Allow specifying rustflags directly in a profile - (unstable, lints, "", "reference/unstable.html#lints"), } pub struct Feature { @@ -734,6 +731,7 @@ unstable_cli_options!( skip_rustdoc_fingerprint: bool = (HIDDEN), rustdoc_scrape_examples: bool = ("Allows Rustdoc to scrape code examples from reverse-dependencies"), msrv_policy: bool = ("Enable rust-version aware policy within cargo"), + lints: bool = ("Pass `[lints]` to the linting tools"), ); const STABILIZED_COMPILE_PROGRESS: &str = "The progress bar is now always \ @@ -1097,6 +1095,7 @@ impl CliUnstable { "codegen-backend" => self.codegen_backend = parse_empty(k, v)?, "profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?, "msrv-policy" => self.msrv_policy = parse_empty(k, v)?, + "lints" => self.lints = parse_empty(k, v)?, _ => bail!("unknown `-Z` flag specified: {}", k), } diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 3cabee8cea9..2c213b7f5fa 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -2045,12 +2045,7 @@ impl TomlManifest { let mut inheritable = toml_config.package.clone().unwrap_or_default(); inheritable.update_ws_path(package_root.to_path_buf()); inheritable.update_deps(toml_config.dependencies.clone()); - let lints = parse_unstable_lints( - toml_config.lints.clone(), - &features, - config, - &mut warnings, - )?; + let lints = parse_unstable_lints(toml_config.lints.clone(), config, &mut warnings)?; let lints = verify_lints(lints)?; inheritable.update_lints(lints); if let Some(ws_deps) = &inheritable.dependencies { @@ -2316,14 +2311,10 @@ impl TomlManifest { &inherit_cell, )?; - let lints = parse_unstable_lints::( - me.lints.clone(), - &features, - config, - cx.warnings, - )? - .map(|mw| mw.resolve("lints", || inherit()?.lints())) - .transpose()?; + let lints = + parse_unstable_lints::(me.lints.clone(), config, cx.warnings)? + .map(|mw| mw.resolve("lints", || inherit()?.lints())) + .transpose()?; let lints = verify_lints(lints)?; let default = TomlLints::default(); let rustflags = lints_to_rustflags(lints.as_ref().unwrap_or(&default)); @@ -2757,12 +2748,7 @@ impl TomlManifest { let mut inheritable = toml_config.package.clone().unwrap_or_default(); inheritable.update_ws_path(root.to_path_buf()); inheritable.update_deps(toml_config.dependencies.clone()); - let lints = parse_unstable_lints( - toml_config.lints.clone(), - &features, - config, - &mut warnings, - )?; + let lints = parse_unstable_lints(toml_config.lints.clone(), config, &mut warnings)?; let lints = verify_lints(lints)?; inheritable.update_lints(lints); let ws_root_config = WorkspaceRootConfig::new( @@ -2911,35 +2897,37 @@ impl TomlManifest { fn parse_unstable_lints>( lints: Option, - features: &Features, config: &Config, warnings: &mut Vec, ) -> CargoResult> { let Some(lints) = lints else { return Ok(None); }; - if !features.is_enabled(Feature::lints()) { - warn_for_feature("lints", config, warnings); + if !config.cli_unstable().lints { + warn_for_lint_feature(config, warnings); return Ok(None); } lints.try_into().map(Some).map_err(|err| err.into()) } -fn warn_for_feature(name: &str, config: &Config, warnings: &mut Vec) { +fn warn_for_lint_feature(config: &Config, warnings: &mut Vec) { use std::fmt::Write as _; + let key_name = "lints"; + let feature_name = "lints"; + let mut message = String::new(); let _ = write!( message, - "feature `{name}` is not supported on this version of Cargo and will be ignored" + "unused manifest key `{key_name}` (may be supported in a future version)" ); if config.nightly_features_allowed { let _ = write!( message, " -consider adding `cargo-features = [\"{name}\"]` to the manifest" +consider passing `-Z{feature_name}` to enable this feature." ); } else { let _ = write!( @@ -2947,8 +2935,8 @@ consider adding `cargo-features = [\"{name}\"]` to the manifest" " this Cargo does not support nightly features, but if you -switch to nightly channel you can add -`cargo-features = [\"{name}\"]` to enable this feature", +switch to nightly channel you can pass +`-Z{feature_name}` to enable this feature.", ); } warnings.push(message); diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 08a84f3f62b..7484db9b582 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -1398,18 +1398,14 @@ Valid operations are the following: A new `lints` table would be added to configure lints: ```toml -cargo-features = ["lints"] - [lints.rust] unsafe = "forbid" ``` -and `cargo` would pass these along as flags to `rustc`, `clippy`, or other lint tools. +and `cargo` would pass these along as flags to `rustc`, `clippy`, or other lint tools when `-Zlints` is used. This would work with [RFC 2906 `workspace-deduplicate`](https://rust-lang.github.io/rfcs/2906-cargo-workspace-deduplicate.html): ```toml -cargo-features = ["lints"] - [lints] workspace = true diff --git a/tests/testsuite/lints.rs b/tests/testsuite/lints.rs index cc834081eb7..fb31da30a98 100644 --- a/tests/testsuite/lints.rs +++ b/tests/testsuite/lints.rs @@ -24,11 +24,11 @@ fn package_requires_option() { foo.cargo("check") .with_stderr( "\ -warning: feature `lints` is not supported on this version of Cargo and will be ignored +warning: unused manifest key `lints` (may be supported in a future version) this Cargo does not support nightly features, but if you -switch to nightly channel you can add -`cargo-features = [\"lints\"]` to enable this feature +switch to nightly channel you can pass +`-Zlints` to enable this feature. [CHECKING] [..] [FINISHED] [..] ", @@ -57,11 +57,11 @@ fn workspace_requires_option() { foo.cargo("check") .with_stderr( "\ -warning: [CWD]/Cargo.toml: feature `lints` is not supported on this version of Cargo and will be ignored +warning: [CWD]/Cargo.toml: unused manifest key `lints` (may be supported in a future version) this Cargo does not support nightly features, but if you -switch to nightly channel you can add -`cargo-features = [\"lints\"]` to enable this feature +switch to nightly channel you can pass +`-Zlints` to enable this feature. [CHECKING] [..] [FINISHED] [..] ", @@ -135,11 +135,11 @@ fn malformed_on_stable() { foo.cargo("check") .with_stderr( "\ -warning: feature `lints` is not supported on this version of Cargo and will be ignored +warning: unused manifest key `lints` (may be supported in a future version) this Cargo does not support nightly features, but if you -switch to nightly channel you can add -`cargo-features = [\"lints\"]` to enable this feature +switch to nightly channel you can pass +`-Zlints` to enable this feature. [CHECKING] [..] [FINISHED] [..] ", @@ -153,7 +153,6 @@ fn malformed_on_nightly() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] lints = 20 [package] name = "foo" @@ -165,7 +164,7 @@ fn malformed_on_nightly() { .file("src/lib.rs", "") .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .with_status(101) .with_stderr( @@ -185,8 +184,6 @@ fn fail_on_invalid_tool() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -199,7 +196,7 @@ fn fail_on_invalid_tool() { .file("src/lib.rs", "") .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .with_status(101) .with_stderr( @@ -219,8 +216,6 @@ fn fail_on_tool_injection() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -233,7 +228,7 @@ fn fail_on_tool_injection() { .file("src/lib.rs", "") .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .with_status(101) .with_stderr( @@ -253,8 +248,6 @@ fn fail_on_redundant_tool() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -267,7 +260,7 @@ fn fail_on_redundant_tool() { .file("src/lib.rs", "") .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .with_status(101) .with_stderr( @@ -287,8 +280,6 @@ fn fail_on_conflicting_tool() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -301,7 +292,7 @@ fn fail_on_conflicting_tool() { .file("src/lib.rs", "") .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .with_status(101) .with_stderr( @@ -321,8 +312,6 @@ fn package_lint_deny() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -342,7 +331,7 @@ pub fn foo(num: i32) -> u32 { ) .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .with_status(101) .with_stderr_contains( @@ -359,8 +348,6 @@ fn workspace_lint_deny() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -383,7 +370,7 @@ pub fn foo(num: i32) -> u32 { ) .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .with_status(101) .with_stderr_contains( @@ -400,8 +387,6 @@ fn attribute_has_precedence() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -423,7 +408,7 @@ pub fn foo(num: i32) -> u32 { ) .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .arg("-v") // Show order of rustflags on failure .masquerade_as_nightly_cargo(&["lints"]) .run(); @@ -435,8 +420,6 @@ fn rustflags_has_precedence() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -456,7 +439,7 @@ pub fn foo(num: i32) -> u32 { ) .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .arg("-v") // Show order of rustflags on failure .env("RUSTFLAGS", "-Aunsafe_code") .masquerade_as_nightly_cargo(&["lints"]) @@ -469,7 +452,7 @@ fn profile_rustflags_has_precedence() { .file( "Cargo.toml", r#" - cargo-features = ["lints", "profile-rustflags"] + cargo-features = ["profile-rustflags"] [package] name = "foo" @@ -492,7 +475,7 @@ pub fn foo(num: i32) -> u32 { ) .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .arg("-v") // Show order of rustflags on failure .masquerade_as_nightly_cargo(&["lints", "profile-rustflags"]) .run(); @@ -504,8 +487,6 @@ fn build_rustflags_has_precedence() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -531,7 +512,7 @@ pub fn foo(num: i32) -> u32 { ) .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .arg("-v") // Show order of rustflags on failure .masquerade_as_nightly_cargo(&["lints"]) .run(); @@ -545,8 +526,6 @@ fn without_priority() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -573,7 +552,7 @@ pub fn foo() -> u32 { ) .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .with_status(101) .with_stderr_contains( @@ -592,8 +571,6 @@ fn with_priority() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -620,7 +597,7 @@ pub fn foo() -> u32 { ) .build(); - foo.cargo("check") + foo.cargo("check -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .run(); } @@ -631,8 +608,6 @@ fn rustdoc_lint() { .file( "Cargo.toml", r#" - cargo-features = ["lints"] - [package] name = "foo" version = "0.0.1" @@ -652,7 +627,7 @@ pub fn foo() -> u32 { ) .build(); - foo.cargo("doc") + foo.cargo("doc -Zlints") .masquerade_as_nightly_cargo(&["lints"]) .with_status(101) .with_stderr_contains(