Change:
EDIT: Prefixing this bug with a better explanation now that I understand better: You can register a custom cfg with in two ways, with a printf in or a in However if your custom cfg is referenced in itself, the printf method does not work (you will get the warning anyway). Worse, the warning triggered by your cfg in will recommend suppressing itself by adding the printf, even though (currently?) that printf will be ineffective. There is a very new (last 2 weeks) Nightly feature which protects against typos in cfg()s by warning if an unexpected cfg is found, comparing against a list of known Rust cfgs. That's useful, but what if your project legitimately uses a cfg that the Rust project did not forsee? According to a new compiler hint along with this feature, you can register a custom cfg in with, for example: In my configuration, this "registration" println does not do anything. Clone this project (branch ), then run : Build with or (the former invokes the latter). You will see four instances of this warning: (Aside: In my tests, build warnings in this project are always printed three times, once with ANSI coloring and twice without, so you'll actually see 12 of this warning, but that's outside the scope of this bug and I think it's my fault). Context: This project builds a video game for an unusual (and low-horsepower) embedded system (hence the submodule). I don't want large support libraries like PNG decoders on the device, so I preprocess large assets such as images in and serialize them using . This means I have a file, , which contains the serialized types, and this file is included in both and the final program. So that this file can work properly in both environments, I put this in my : So this means I can use to verify I'm in the built program and to verify I'm in This is the cfg warns about. Fair enough, let's notify of this custom cfg so we don't get the warning. At the top of main() is this line; uncomment it: (This is of course the action recommended by the hint in the warning.) Now re-run the build with . You will see… the exact same four errors. The rustc-check-cfg printout does nothing. I have not experimented with disabling the warning with . The warning seems good because it catches typos. I just don't want to be warned about because it's not a typo. In the repro I use the single colon version of , because that feature only works when Rust MSRV is above 1.77, and requiring Rust 1.80 in order to banish a warning that didn't exist before Rust 1.80 seems silly. However, I did test with double colon and it didn't behave any different. It seems to me that since the file is included in both and the built program, even if suppressed the warnings about the surplus config in the program I might still wind up facing warnings about in the , since the println has not run at the time the is built. However I don't think this is the problem above, because in that case I would have expected the number of warnings to halve on adding the suppression line, not stay the same. In case you were wondering, yes I see the warning both on and .
Your analysis here is correct, I think you just missed this tiny note which is that cargo suppresses identical warnings Before uncommenting the line: After: what's the right way to deal with warnings originating in ?
Adding the check-cfg args directly in the lint config should do it[^1][^2]. : [^1]: Note that this was very recently, around 2 nightly version ago, be sure to update to the latest nightly. [^2]: Note that using the lint config currently produce a warning on beta, we are working on fixing that.
Thank you, I should have updated to NEWEST nightly before filing. I see that with 2024-05-20 nightly rustc the [lint] IS recommended in a hint, so this hint would have solved my problem if I had upgraded this morning before filing. The lint works as expected and my problem is resolved (lint removes warnings where println does not). I have a recommendation. If you are merging and executable warnings, then in principle you know that my "exe" cfg warnings are coming (in part) from Currently, you display two recommendations, the print and the [lint]. In the case of a cfg warning originating from a , the print! will not help and you know that ahead of time. Therefore for these warnings, I suggest you omit the print recommendation and show only the [lint] recommendation. If that is impractical, then you may close this issue.  with I get:
Yeah, I'm using Rust 1.81.0, within my , I have: Then I have a very simple : These are the warnings I get from : I tried adding the suggested fixes to : It does not work at all.

Discussion:
} } <ins> fn cargo_help_sub( sess: &Session, inst: &impl Fn(EscapeQuotes) -> String, ) -> lints::UnexpectedCfgCargoHelp { // We don't want to suggest the `build.rs` way to expected cfgs if we are already in a // `build.rs`. We therefor do a best effort check (looking if the `--crate-name` is // `build_script_build`) to try to figure out if we are building a Cargo build script let unescaped = &inst(EscapeQuotes::No); if matches!(&sess.opts.crate_name, Some(crate_name) if crate_name == "build_script_build") { lints::UnexpectedCfgCargoHelp::lint_cfg(unescaped) } else { lints::UnexpectedCfgCargoHelp::lint_cfg_and_build_rs(unescaped, &inst(EscapeQuotes::Yes)) } } </ins> pub(super) fn unexpected_cfg_name( sess: &Session, (name, name_span): (Symbol, Span),

let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes); let invocation_help = if is_from_cargo { <del> let sub = if !is_feature_cfg { Some(lints::UnexpectedCfgCargoHelp::new( &inst(EscapeQuotes::No), &inst(EscapeQuotes::Yes), )) } else { None }; </del> <ins> let sub = if !is_feature_cfg { Some(cargo_help_sub(sess, &inst)) } else { None }; </ins> lints::unexpected_cfg_name::InvocationHelp::Cargo { sub } } else { lints::unexpected_cfg_name::InvocationHelp::Rustc(lints::UnexpectedCfgRustcHelp::new(

Some(lints::unexpected_cfg_value::CargoHelp::DefineFeatures) } } else if !is_cfg_a_well_know_name { <del> Some(lints::unexpected_cfg_value::CargoHelp::Other(lints::UnexpectedCfgCargoHelp::new( &inst(EscapeQuotes::No), &inst(EscapeQuotes::Yes), ))) </del> <ins> Some(lints::unexpected_cfg_value::CargoHelp::Other(cargo_help_sub(sess, &inst))) </ins> } else { None };

pub struct BuiltinNamedAsmLabel; #[derive(Subdiagnostic)] <del> #[help(lint_unexpected_cfg_add_cargo_feature)] #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)] #[help(lint_unexpected_cfg_add_build_rs_println)] pub struct UnexpectedCfgCargoHelp { pub build_rs_println: String, pub cargo_toml_lint_cfg: String, </del> <ins> pub enum UnexpectedCfgCargoHelp { #[help(lint_unexpected_cfg_add_cargo_feature)] #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)] LintCfg { cargo_toml_lint_cfg: String }, #[help(lint_unexpected_cfg_add_cargo_feature)] #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)] #[help(lint_unexpected_cfg_add_build_rs_println)] LintCfgAndBuildRs { cargo_toml_lint_cfg: String, build_rs_println: String }, </ins> } impl UnexpectedCfgCargoHelp { <del> pub fn new(unescaped: &str, escaped: &str) -> Self { Self { cargo_toml_lint_cfg: format!( "n [lints.rust]n unexpected_cfgs = {{ level = "warn", check-cfg = ['{unescaped}'] }}", ), build_rs_println: format!("println!("cargo::rustc-check-cfg={escaped}");",), </del> <ins> fn cargo_toml_lint_cfg(unescaped: &str) -> String { format!( "n [lints.rust]n unexpected_cfgs = {{ level = "warn", check-cfg = ['{unescaped}'] }}" ) } pub fn lint_cfg(unescaped: &str) -> Self { UnexpectedCfgCargoHelp::LintCfg { cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped), } } pub fn lint_cfg_and_build_rs(unescaped: &str, escaped: &str) -> Self { UnexpectedCfgCargoHelp::LintCfgAndBuildRs { cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped), build_rs_println: format!("println!("cargo::rustc-check-cfg={escaped}");"), </ins> } } }

<ins> // This test checks that when we are building a build script provided // by Cargo we only suggest expecting the unexpected cfgs in the Cargo.toml. // //@ check-pass //@ no-auto-check-cfg //@ rustc-env:CARGO_CRATE_NAME=build_script_build //@ compile-flags:--crate-name=build_script_build //@ compile-flags:--check-cfg=cfg(has_bar) #[cfg(has_foo)] //~^ WARNING unexpected `cfg` condition name fn foo() {} #[cfg(has_foo = "yes")] //~^ WARNING unexpected `cfg` condition name fn foo() {} #[cfg(has_bar = "yes")] //~^ WARNING unexpected `cfg` condition value fn has_bar() {} fn main() {} </ins>

<ins> warning: unexpected `cfg` condition name: `has_foo` --> $DIR/cargo-build-script.rs:10:7 | LL | #[cfg(has_foo)] |       ^^^^^^^ | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `has_bar`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows` = help: consider using a Cargo feature instead = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(has_foo)'] } = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `has_foo` --> $DIR/cargo-build-script.rs:14:7 | LL | #[cfg(has_foo = "yes")] |       ^^^^^^^^^^^^^^^ | = help: consider using a Cargo feature instead = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(has_foo, values("yes"))'] } = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `yes` --> $DIR/cargo-build-script.rs:18:7 | LL | #[cfg(has_bar = "yes")] |       ^^^^^^^-------- |              | |              help: remove the value | = note: no expected value for `has_bar` = help: consider using a Cargo feature instead = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(has_bar, values("yes"))'] } = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration warning: 3 warnings emitted </ins>