mirror of
https://github.com/rust-lang/cargo
synced 2024-08-27 19:29:21 +00:00
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:
commit
feb9bcf630
|
@ -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),
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue