Add typo suggestion for a misspelt Cargo environment variable
This commit is contained in:
parent
401ae55427
commit
3edd25f049
5 changed files with 170 additions and 0 deletions
|
|
@ -156,6 +156,7 @@ builtin_macros_duplicate_macro_attribute = duplicated attribute
|
|||
|
||||
builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time
|
||||
.cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead
|
||||
.cargo_typo = there is a similar Cargo environment variable: `{$suggested_var}`
|
||||
.custom = use `std::env::var({$var_expr})` to read the variable at run time
|
||||
|
||||
builtin_macros_env_not_unicode = environment variable `{$var}` is not a valid Unicode string
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use rustc_ast::token::{self, LitKind};
|
|||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_ast::{ExprKind, GenericArg, Mutability};
|
||||
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
|
||||
use rustc_span::edit_distance::edit_distance;
|
||||
use rustc_span::{Ident, Span, Symbol, kw, sym};
|
||||
use thin_vec::thin_vec;
|
||||
|
||||
|
|
@ -144,6 +145,12 @@ pub(crate) fn expand_env<'cx>(
|
|||
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()) {
|
||||
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()) {
|
||||
cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar {
|
||||
span,
|
||||
|
|
@ -176,3 +183,49 @@ fn is_cargo_env_var(var: &str) -> bool {
|
|||
|| var.starts_with("DEP_")
|
||||
|| matches!(var, "OUT_DIR" | "OPT_LEVEL" | "PROFILE" | "HOST" | "TARGET")
|
||||
}
|
||||
|
||||
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",
|
||||
"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",
|
||||
];
|
||||
|
||||
fn find_similar_cargo_var(var: &str) -> Option<&'static str> {
|
||||
if !var.starts_with("CARGO_") {
|
||||
return None;
|
||||
}
|
||||
|
||||
let lookup_len = var.chars().count();
|
||||
let max_dist = std::cmp::max(lookup_len, 3) / 3;
|
||||
let mut best_match = None;
|
||||
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 distance < best_distance {
|
||||
best_distance = distance;
|
||||
best_match = Some(known_var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
best_match
|
||||
}
|
||||
|
|
|
|||
|
|
@ -535,6 +535,14 @@ pub(crate) enum EnvNotDefined<'a> {
|
|||
var_expr: &'a rustc_ast::Expr,
|
||||
},
|
||||
#[diag(builtin_macros_env_not_defined)]
|
||||
#[help(builtin_macros_cargo_typo)]
|
||||
CargoEnvVarTypo {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
var: Symbol,
|
||||
suggested_var: Symbol,
|
||||
},
|
||||
#[diag(builtin_macros_env_not_defined)]
|
||||
#[help(builtin_macros_custom)]
|
||||
CustomEnvVar {
|
||||
#[primary_span]
|
||||
|
|
|
|||
50
tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs
Normal file
50
tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
//@ edition: 2021
|
||||
|
||||
// Regression test for issue #148439
|
||||
// Ensure that when using misspelled Cargo environment variables in env!(),
|
||||
|
||||
fn test_cargo_package_version() {
|
||||
let _ = env!("CARGO_PACKAGE_VERSION");
|
||||
//~^ ERROR environment variable `CARGO_PACKAGE_VERSION` not defined at compile time
|
||||
//~| HELP there is a similar Cargo environment variable: `CARGO_PKG_VERSION`
|
||||
}
|
||||
|
||||
fn test_cargo_package_name() {
|
||||
let _ = env!("CARGO_PACKAGE_NAME");
|
||||
//~^ ERROR environment variable `CARGO_PACKAGE_NAME` not defined at compile time
|
||||
//~| HELP there is a similar Cargo environment variable: `CARGO_PKG_NAME`
|
||||
}
|
||||
|
||||
fn test_cargo_package_authors() {
|
||||
let _ = env!("CARGO_PACKAGE_AUTHORS");
|
||||
//~^ ERROR environment variable `CARGO_PACKAGE_AUTHORS` not defined at compile time
|
||||
//~| HELP there is a similar Cargo environment variable: `CARGO_PKG_AUTHORS`
|
||||
}
|
||||
|
||||
fn test_cargo_manifest_directory() {
|
||||
let _ = env!("CARGO_MANIFEST_DIRECTORY");
|
||||
//~^ ERROR environment variable `CARGO_MANIFEST_DIRECTORY` not defined at compile time
|
||||
//~| HELP there is a similar Cargo environment variable: `CARGO_MANIFEST_DIR`
|
||||
}
|
||||
|
||||
fn test_cargo_pkg_version_typo() {
|
||||
let _ = env!("CARGO_PKG_VERSIO");
|
||||
//~^ ERROR environment variable `CARGO_PKG_VERSIO` not defined at compile time
|
||||
//~| HELP there is a similar Cargo environment variable: `CARGO_PKG_VERSION`
|
||||
}
|
||||
|
||||
fn test_non_cargo_var() {
|
||||
// Non-Cargo variable should get different help message
|
||||
let _ = env!("MY_CUSTOM_VAR");
|
||||
//~^ ERROR environment variable `MY_CUSTOM_VAR` not defined at compile time
|
||||
//~| HELP use `std::env::var("MY_CUSTOM_VAR")` to read the variable at run time
|
||||
}
|
||||
|
||||
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 sets build script variables at run time. Use `std::env::var("CARGO_SOMETHING_TOTALLY_UNKNOWN")` instead
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
58
tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr
Normal file
58
tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
error: environment variable `CARGO_PACKAGE_VERSION` not defined at compile time
|
||||
--> $DIR/env-cargo-var-typo-issue-148439.rs:7: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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
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
|
||||
|
|
||||
LL | let _ = env!("CARGO_SOMETHING_TOTALLY_UNKNOWN");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue