From 57650eeb9dd4d4af3cf265c360864716b2badc4f Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Sat, 7 Feb 2026 17:24:16 +0100 Subject: [PATCH] fix: don't suggest replacing `env!("CARGO_BIN_NAME")` with itself --- compiler/rustc_builtin_macros/src/env.rs | 44 ++++++++++++------- compiler/rustc_builtin_macros/src/errors.rs | 1 + .../env-cargo-var-typo-issue-148439.rs | 10 ++++- .../env-cargo-var-typo-issue-148439.stderr | 26 +++++++---- .../env-macro/env-not-defined-default.stderr | 1 + 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index af78db156a221..12f59467ffd16 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -140,18 +140,21 @@ pub(crate) fn expand_env<'cx>( unreachable!("`expr_to_string` ensures this is a string lit") }; + let var = var.as_str(); let guar = match err { VarError::NotPresent => { if let Some(msg_from_user) = custom_msg { cx.dcx() .emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user }) - } else if let Some(suggested_var) = find_similar_cargo_var(var.as_str()) { + } else if let Some(suggested_var) = find_similar_cargo_var(var) + && suggested_var != var + { cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVarTypo { span, var: *symbol, suggested_var: Symbol::intern(suggested_var), }) - } else if is_cargo_env_var(var.as_str()) { + } else if is_cargo_env_var(var) { cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar { span, var: *symbol, @@ -177,7 +180,7 @@ pub(crate) fn expand_env<'cx>( ExpandResult::Ready(MacEager::expr(e)) } -/// Returns `true` if an environment variable from `env!` is one used by Cargo. +/// Returns `true` if an environment variable from `env!` could be one used by Cargo. fn is_cargo_env_var(var: &str) -> bool { var.starts_with("CARGO_") || var.starts_with("DEP_") @@ -187,25 +190,28 @@ fn is_cargo_env_var(var: &str) -> bool { const KNOWN_CARGO_VARS: &[&str] = &[ // List of known Cargo environment variables that are set for crates (not build scripts, OUT_DIR etc). // See: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates - "CARGO_PKG_VERSION", - "CARGO_PKG_VERSION_MAJOR", - "CARGO_PKG_VERSION_MINOR", - "CARGO_PKG_VERSION_PATCH", - "CARGO_PKG_VERSION_PRE", + // tidy-alphabetical-start + "CARGO_BIN_NAME", + "CARGO_CRATE_NAME", + "CARGO_MANIFEST_DIR", + "CARGO_MANIFEST_PATH", "CARGO_PKG_AUTHORS", - "CARGO_PKG_NAME", "CARGO_PKG_DESCRIPTION", "CARGO_PKG_HOMEPAGE", - "CARGO_PKG_REPOSITORY", "CARGO_PKG_LICENSE", "CARGO_PKG_LICENSE_FILE", - "CARGO_PKG_RUST_VERSION", + "CARGO_PKG_NAME", "CARGO_PKG_README", - "CARGO_MANIFEST_DIR", - "CARGO_MANIFEST_PATH", - "CARGO_CRATE_NAME", - "CARGO_BIN_NAME", + "CARGO_PKG_REPOSITORY", + "CARGO_PKG_RUST_VERSION", + "CARGO_PKG_VERSION", + "CARGO_PKG_VERSION_MAJOR", + "CARGO_PKG_VERSION_MINOR", + "CARGO_PKG_VERSION_PATCH", + "CARGO_PKG_VERSION_PRE", "CARGO_PRIMARY_PACKAGE", + "CARGO_TARGET_TMPDIR", + // tidy-alphabetical-end ]; fn find_similar_cargo_var(var: &str) -> Option<&'static str> { @@ -219,7 +225,13 @@ fn find_similar_cargo_var(var: &str) -> Option<&'static str> { let mut best_distance = usize::MAX; for &known_var in KNOWN_CARGO_VARS { - if let Some(distance) = edit_distance(var, known_var, max_dist) { + if let Some(mut distance) = edit_distance(var, known_var, max_dist) { + // assume `PACKAGE` to equals `PKG` + // (otherwise, `d("CARGO_PACKAGE_NAME", "CARGO_PKG_NAME") == d("CARGO_PACKAGE_NAME", "CARGO_CRATE_NAME") == 4`) + if var.contains("PACKAGE") && known_var.contains("PKG") { + distance = distance.saturating_sub(const { "PACKAGE".len() - "PKG".len() }) // == d("PACKAGE", "PKG") + } + if distance < best_distance { best_distance = distance; best_match = Some(known_var); diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index d3f7e1c5d8e36..e57d3f621f698 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -544,6 +544,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for EnvNotDefinedWithUserMessag #[derive(Diagnostic)] pub(crate) enum EnvNotDefined<'a> { #[diag("environment variable `{$var}` not defined at compile time")] + #[help("`{$var}` may not be available for the current Cargo target")] #[help( "Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead" )] diff --git a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs index f859decd09ecb..f72b43bb2543c 100644 --- a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs +++ b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs @@ -1,4 +1,5 @@ //@ edition: 2021 +//@ compile-flags: --crate-type=lib // Regression test for issue #148439 // Ensure that when using misspelled Cargo environment variables in env!(), @@ -44,7 +45,14 @@ fn test_cargo_unknown_var() { // Cargo-prefixed but not similar to any known variable let _ = env!("CARGO_SOMETHING_TOTALLY_UNKNOWN"); //~^ ERROR environment variable `CARGO_SOMETHING_TOTALLY_UNKNOWN` not defined at compile time + //~| HELP `CARGO_SOMETHING_TOTALLY_UNKNOWN` may not be available for the current Cargo target //~| HELP Cargo sets build script variables at run time. Use `std::env::var("CARGO_SOMETHING_TOTALLY_UNKNOWN")` instead } -fn main() {} +fn test_cargo_conditional_var() { + // Only set for binairies + let _ = env!("CARGO_BIN_NAME"); + //~^ ERROR environment variable `CARGO_BIN_NAME` not defined at compile time + //~| HELP `CARGO_BIN_NAME` may not be available for the current Cargo target + //~| HELP Cargo sets build script variables at run time. Use `std::env::var("CARGO_BIN_NAME")` instead +} diff --git a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr index e16c4d9a1f4c2..50a4cf1a616be 100644 --- a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr +++ b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr @@ -1,5 +1,5 @@ error: environment variable `CARGO_PACKAGE_VERSION` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:7:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:8:13 | LL | let _ = env!("CARGO_PACKAGE_VERSION"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | let _ = env!("CARGO_PACKAGE_VERSION"); = help: there is a similar Cargo environment variable: `CARGO_PKG_VERSION` error: environment variable `CARGO_PACKAGE_NAME` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:13:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:14:13 | LL | let _ = env!("CARGO_PACKAGE_NAME"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | let _ = env!("CARGO_PACKAGE_NAME"); = help: there is a similar Cargo environment variable: `CARGO_PKG_NAME` error: environment variable `CARGO_PACKAGE_AUTHORS` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:19:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:20:13 | LL | let _ = env!("CARGO_PACKAGE_AUTHORS"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = env!("CARGO_PACKAGE_AUTHORS"); = help: there is a similar Cargo environment variable: `CARGO_PKG_AUTHORS` error: environment variable `CARGO_MANIFEST_DIRECTORY` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:25:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:26:13 | LL | let _ = env!("CARGO_MANIFEST_DIRECTORY"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | let _ = env!("CARGO_MANIFEST_DIRECTORY"); = help: there is a similar Cargo environment variable: `CARGO_MANIFEST_DIR` error: environment variable `CARGO_PKG_VERSIO` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:31:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:32:13 | LL | let _ = env!("CARGO_PKG_VERSIO"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | let _ = env!("CARGO_PKG_VERSIO"); = help: there is a similar Cargo environment variable: `CARGO_PKG_VERSION` error: environment variable `MY_CUSTOM_VAR` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:38:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:39:13 | LL | let _ = env!("MY_CUSTOM_VAR"); | ^^^^^^^^^^^^^^^^^^^^^ @@ -47,12 +47,22 @@ LL | let _ = env!("MY_CUSTOM_VAR"); = help: use `std::env::var("MY_CUSTOM_VAR")` to read the variable at run time error: environment variable `CARGO_SOMETHING_TOTALLY_UNKNOWN` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:45:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:46:13 | LL | let _ = env!("CARGO_SOMETHING_TOTALLY_UNKNOWN"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: `CARGO_SOMETHING_TOTALLY_UNKNOWN` may not be available for the current Cargo target = help: Cargo sets build script variables at run time. Use `std::env::var("CARGO_SOMETHING_TOTALLY_UNKNOWN")` instead -error: aborting due to 7 previous errors +error: environment variable `CARGO_BIN_NAME` not defined at compile time + --> $DIR/env-cargo-var-typo-issue-148439.rs:54:13 + | +LL | let _ = env!("CARGO_BIN_NAME"); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `CARGO_BIN_NAME` may not be available for the current Cargo target + = help: Cargo sets build script variables at run time. Use `std::env::var("CARGO_BIN_NAME")` instead + +error: aborting due to 8 previous errors diff --git a/tests/ui/env-macro/env-not-defined-default.stderr b/tests/ui/env-macro/env-not-defined-default.stderr index 77ba00e45c1c6..8340bb0e8fba6 100644 --- a/tests/ui/env-macro/env-not-defined-default.stderr +++ b/tests/ui/env-macro/env-not-defined-default.stderr @@ -4,6 +4,7 @@ error: environment variable `CARGO__HOPEFULLY_NOT_DEFINED__` not defined at comp LL | env!("CARGO__HOPEFULLY_NOT_DEFINED__"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: `CARGO__HOPEFULLY_NOT_DEFINED__` may not be available for the current Cargo target = help: Cargo sets build script variables at run time. Use `std::env::var("CARGO__HOPEFULLY_NOT_DEFINED__")` instead error: aborting due to 1 previous error