Auto merge of #12168 - epage:lints2, r=weihanglo

fix(lints): Switch to -Zlints so stable projects can experiment

### What does this PR try to resolve?

In #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.

### How should we test and review this PR?

Demonstrate how you test this change and guide reviewers through your PR.
With a smooth review process, a pull request usually gets reviewed quicker.

If you don't know how to write and run your tests, please read the guide:
https://doc.crates.io/contrib/tests

### Additional information

I considered reworking the code to show the user the errors they would encounter once the feature is stable but held off.  I wasn't quite sure what language to use and most likely a user would have something doing error reporting, like CI, so it should be fine.
This commit is contained in:
bors 2023-05-23 13:52:22 +00:00
commit feb9bcf630
4 changed files with 44 additions and 86 deletions

View file

@ -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),
}

View file

@ -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::<MaybeWorkspaceLints>(
me.lints.clone(),
&features,
config,
cx.warnings,
)?
.map(|mw| mw.resolve("lints", || inherit()?.lints()))
.transpose()?;
let lints =
parse_unstable_lints::<MaybeWorkspaceLints>(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<T: Deserialize<'static>>(
lints: Option<toml::Value>,
features: &Features,
config: &Config,
warnings: &mut Vec<String>,
) -> CargoResult<Option<T>> {
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<String>) {
fn warn_for_lint_feature(config: &Config, warnings: &mut Vec<String>) {
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);

View file

@ -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

View file

@ -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", "profile-rustflags"]
[package]
name = "foo"
version = "0.0.1"
@ -531,9 +512,9 @@ 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"])
.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(