From abf095329233c507e5e718ade9b0a932c53c3e6e Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Sat, 23 Mar 2024 10:24:50 -0600 Subject: [PATCH 1/2] feat: Add `-Zcargo-lints` --- src/cargo/core/features.rs | 2 + src/cargo/util/toml/mod.rs | 51 +++++++++- tests/testsuite/cargo/z_help/stdout.term.svg | 66 ++++++------- tests/testsuite/lints_table.rs | 99 +++++++++++++++++++- 4 files changed, 180 insertions(+), 38 deletions(-) diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 24e208fc913..a78598e82e0 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -750,6 +750,7 @@ unstable_cli_options!( #[serde(deserialize_with = "deserialize_build_std")] build_std: Option> = ("Enable Cargo to compile the standard library itself as part of a crate graph compilation"), build_std_features: Option> = ("Configure features enabled for the standard library itself when building the standard library"), + cargo_lints: bool = ("Enable the `[lints.cargo]` table"), check_cfg: bool = ("Enable compile-time checking of `cfg` names/values/features"), codegen_backend: bool = ("Enable the `codegen-backend` option in profiles in .cargo/config.toml file"), config_include: bool = ("Enable the `include` key in config files"), @@ -1117,6 +1118,7 @@ impl CliUnstable { self.build_std = Some(crate::core::compiler::standard_lib::parse_unstable_flag(v)) } "build-std-features" => self.build_std_features = Some(parse_features(v)), + "cargo-lints" => self.cargo_lints = parse_empty(k, v)?, "check-cfg" => { self.check_cfg = parse_empty(k, v)?; } diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 3898695fbe7..3a4fd6847ae 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -494,7 +494,7 @@ pub fn to_real_manifest( let workspace_config = match (original_toml.workspace.as_ref(), package.workspace.as_ref()) { (Some(toml_config), None) => { - verify_lints(toml_config.lints.as_ref())?; + verify_lints(toml_config.lints.as_ref(), gctx, &mut warnings)?; if let Some(ws_deps) = &toml_config.dependencies { for (name, dep) in ws_deps { unused_dep_keys( @@ -828,7 +828,7 @@ pub fn to_real_manifest( .clone() .map(|mw| lints_inherit_with(mw, || inherit()?.lints())) .transpose()?; - verify_lints(lints.as_ref())?; + verify_lints(lints.as_ref(), gctx, manifest_ctx.warnings)?; let default = manifest::TomlLints::default(); let rustflags = lints_to_rustflags(lints.as_ref().unwrap_or(&default)); @@ -1322,7 +1322,7 @@ fn to_virtual_manifest( .transpose()?; let workspace_config = match original_toml.workspace { Some(ref toml_config) => { - verify_lints(toml_config.lints.as_ref())?; + verify_lints(toml_config.lints.as_ref(), gctx, &mut warnings)?; let ws_root_config = to_workspace_config(toml_config, root); gctx.ws_roots .borrow_mut() @@ -1448,17 +1448,24 @@ struct ManifestContext<'a, 'b> { features: &'a Features, } -fn verify_lints(lints: Option<&manifest::TomlLints>) -> CargoResult<()> { +fn verify_lints( + lints: Option<&manifest::TomlLints>, + gctx: &GlobalContext, + warnings: &mut Vec, +) -> CargoResult<()> { let Some(lints) = lints else { return Ok(()); }; for (tool, lints) in lints { - let supported = ["rust", "clippy", "rustdoc"]; + let supported = ["cargo", "clippy", "rust", "rustdoc"]; if !supported.contains(&tool.as_str()) { let supported = supported.join(", "); anyhow::bail!("unsupported `{tool}` in `[lints]`, must be one of {supported}") } + if tool == "cargo" && !gctx.cli_unstable().cargo_lints { + warn_for_cargo_lint_feature(gctx, warnings); + } for name in lints.keys() { if let Some((prefix, suffix)) = name.split_once("::") { if tool == prefix { @@ -1479,9 +1486,43 @@ fn verify_lints(lints: Option<&manifest::TomlLints>) -> CargoResult<()> { Ok(()) } +fn warn_for_cargo_lint_feature(gctx: &GlobalContext, warnings: &mut Vec) { + use std::fmt::Write as _; + + let key_name = "lints.cargo"; + let feature_name = "cargo-lints"; + + let mut message = String::new(); + + let _ = write!( + message, + "unused manifest key `{key_name}` (may be supported in a future version)" + ); + if gctx.nightly_features_allowed { + let _ = write!( + message, + " + +consider passing `-Z{feature_name}` to enable this feature." + ); + } else { + let _ = write!( + message, + " + +this Cargo does not support nightly features, but if you +switch to nightly channel you can pass +`-Z{feature_name}` to enable this feature.", + ); + } + warnings.push(message); +} + fn lints_to_rustflags(lints: &manifest::TomlLints) -> Vec { let mut rustflags = lints .iter() + // We don't want to pass any of the `cargo` lints to `rustc` + .filter(|(tool, _)| tool != &"cargo") .flat_map(|(tool, lints)| { lints.iter().map(move |(name, config)| { let flag = match config.level() { diff --git a/tests/testsuite/cargo/z_help/stdout.term.svg b/tests/testsuite/cargo/z_help/stdout.term.svg index 5848c09f543..f500049ae58 100644 --- a/tests/testsuite/cargo/z_help/stdout.term.svg +++ b/tests/testsuite/cargo/z_help/stdout.term.svg @@ -1,4 +1,4 @@ - +