Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 28 additions & 16 deletions compiler/rustc_builtin_macros/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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_")
Expand All @@ -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> {
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)]
Expand Down
10 changes: 9 additions & 1 deletion tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs
Original file line number Diff line number Diff line change
@@ -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!(),
Expand Down Expand Up @@ -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
}
26 changes: 18 additions & 8 deletions tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr
Original file line number Diff line number Diff line change
@@ -1,58 +1,68 @@
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");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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");
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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");
| ^^^^^^^^^^^^^^^^^^^^^
|
= 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

1 change: 1 addition & 0 deletions tests/ui/env-macro/env-not-defined-default.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading