fix: don't suggest replacing env!("CARGO_BIN_NAME") with itself

This commit is contained in:
Lieselotte
2026-02-07 17:24:16 +01:00
parent 06cafcbe08
commit 57650eeb9d
5 changed files with 58 additions and 26 deletions
+29 -17
View File
@@ -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
// tidy-alphabetical-start
"CARGO_BIN_NAME",
"CARGO_CRATE_NAME",
"CARGO_MANIFEST_DIR",
"CARGO_MANIFEST_PATH",
"CARGO_PKG_AUTHORS",
"CARGO_PKG_DESCRIPTION",
"CARGO_PKG_HOMEPAGE",
"CARGO_PKG_LICENSE",
"CARGO_PKG_LICENSE_FILE",
"CARGO_PKG_NAME",
"CARGO_PKG_README",
"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_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_README",
"CARGO_MANIFEST_DIR",
"CARGO_MANIFEST_PATH",
"CARGO_CRATE_NAME",
"CARGO_BIN_NAME",
"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);
@@ -544,6 +544,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
#[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"
)]
@@ -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
}
@@ -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
@@ -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