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
8 changes: 4 additions & 4 deletions compiler/rustc_builtin_macros/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,23 +562,23 @@ pub(crate) enum EnvNotDefined {
CargoEnvVar {
#[primary_span]
span: Span,
var: Symbol,
var: String,
var_expr: String,
},
#[diag("environment variable `{$var}` not defined at compile time")]
#[help("there is a similar Cargo environment variable: `{$suggested_var}`")]
CargoEnvVarTypo {
#[primary_span]
span: Span,
var: Symbol,
var: String,
suggested_var: Symbol,
},
#[diag("environment variable `{$var}` not defined at compile time")]
#[help("use `std::env::var({$var_expr})` to read the variable at run time")]
CustomEnvVar {
#[primary_span]
span: Span,
var: Symbol,
var: String,
var_expr: String,
},
}
Expand All @@ -588,7 +588,7 @@ pub(crate) enum EnvNotDefined {
pub(crate) struct EnvNotUnicode {
#[primary_span]
pub(crate) span: Span,
pub(crate) var: Symbol,
pub(crate) var: String,
}

#[derive(Diagnostic)]
Expand Down
86 changes: 34 additions & 52 deletions compiler/rustc_builtin_macros/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
use std::env;
use std::env::VarError;

use rustc_ast::token::{self, LitKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{ExprKind, GenericArg, Mutability};
use rustc_ast::{GenericArg, Mutability};
use rustc_ast_pretty::pprust;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_span::edit_distance::edit_distance;
Expand Down Expand Up @@ -69,14 +68,8 @@ pub(crate) fn expand_option_env<'cx>(
))
}
Err(VarError::NotUnicode(_)) => {
let ExprKind::Lit(token::Lit {
kind: LitKind::Str | LitKind::StrRaw(..), symbol, ..
}) = &var_expr.kind
else {
unreachable!("`expr_to_string` ensures this is a string lit")
};

let guar = cx.dcx().emit_err(diagnostics::EnvNotUnicode { span: sp, var: *symbol });
let escaped_var = var.as_str().escape_debug().to_string();
let guar = cx.dcx().emit_err(diagnostics::EnvNotUnicode { span: sp, var: escaped_var });
return ExpandResult::Ready(DummyResult::any(sp, guar));
}
Ok(value) => cx.expr_call_global(
Expand Down Expand Up @@ -106,6 +99,7 @@ pub(crate) fn expand_env<'cx>(
};

let var_expr = exprs.next().unwrap();
// FIXME: `get_exprs_from_tts()` already performed macro expansion...
let ExpandResult::Ready(mac) = expr_to_string(cx, var_expr.clone(), "expected string literal")
else {
return ExpandResult::Retry(());
Expand Down Expand Up @@ -133,49 +127,37 @@ pub(crate) fn expand_env<'cx>(
let value = lookup_env(cx, var);
cx.sess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied()));
let e = match value {
Err(err) => {
let ExprKind::Lit(token::Lit {
kind: LitKind::Str | LitKind::StrRaw(..), symbol, ..
}) = &var_expr.kind
else {
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(diagnostics::EnvNotDefinedWithUserMessage {
span,
msg_from_user,
})
} else if let Some(suggested_var) = find_similar_cargo_var(var)
&& suggested_var != var
{
cx.dcx().emit_err(diagnostics::EnvNotDefined::CargoEnvVarTypo {
span,
var: *symbol,
suggested_var: Symbol::intern(suggested_var),
})
} else if is_cargo_env_var(var) {
cx.dcx().emit_err(diagnostics::EnvNotDefined::CargoEnvVar {
span,
var: *symbol,
var_expr: pprust::expr_to_string(&var_expr),
})
} else {
cx.dcx().emit_err(diagnostics::EnvNotDefined::CustomEnvVar {
span,
var: *symbol,
var_expr: pprust::expr_to_string(&var_expr),
})
}
}
VarError::NotUnicode(_) => {
cx.dcx().emit_err(diagnostics::EnvNotUnicode { span, var: *symbol })
}
Err(VarError::NotPresent) => {
let var_str = var.as_str();
let escaped_var = var_str.escape_debug().to_string();
let guar = if let Some(msg_from_user) = custom_msg {
cx.dcx().emit_err(diagnostics::EnvNotDefinedWithUserMessage { span, msg_from_user })
} else if let Some(suggested_var) = find_similar_cargo_var(var_str)
&& suggested_var != var_str
{
cx.dcx().emit_err(diagnostics::EnvNotDefined::CargoEnvVarTypo {
span,
var: escaped_var,
suggested_var: Symbol::intern(suggested_var),
})
} else if is_cargo_env_var(var_str) {
cx.dcx().emit_err(diagnostics::EnvNotDefined::CargoEnvVar {
span,
var: escaped_var,
var_expr: pprust::expr_to_string(&var_expr),
})
} else {
cx.dcx().emit_err(diagnostics::EnvNotDefined::CustomEnvVar {
span,
var: escaped_var,
var_expr: pprust::expr_to_string(&var_expr),
})
};

return ExpandResult::Ready(DummyResult::any(sp, guar));
}
Err(VarError::NotUnicode(_)) => {
let escaped_var = var.as_str().escape_debug().to_string();
let guar = cx.dcx().emit_err(diagnostics::EnvNotUnicode { span, var: escaped_var });
return ExpandResult::Ready(DummyResult::any(sp, guar));
}
Ok(value) => cx.expr_str(span, value),
Expand Down
8 changes: 8 additions & 0 deletions tests/run-make/non-unicode-env/non_unicode_env.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
macro_rules! var_named_via_macro {
() => {
"NON_UNICODE_VAR"
};
}

fn main() {
let _ = env!("NON_UNICODE_VAR");
let _ = option_env!("NON_UNICODE_VAR");
let _ = env!(var_named_via_macro!());
let _ = option_env!(var_named_via_macro!());
}
21 changes: 16 additions & 5 deletions tests/run-make/non-unicode-env/non_unicode_env.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string
--> non_unicode_env.rs:2:13
--> non_unicode_env.rs:8:13
|
2 | let _ = env!("NON_UNICODE_VAR");
8 | let _ = env!("NON_UNICODE_VAR");
| ^^^^^^^^^^^^^^^^^^^^^^^

error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string
--> non_unicode_env.rs:3:13
--> non_unicode_env.rs:9:13
|
3 | let _ = option_env!("NON_UNICODE_VAR");
9 | let _ = option_env!("NON_UNICODE_VAR");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors
error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string
--> non_unicode_env.rs:10:13
|
10 | let _ = env!(var_named_via_macro!());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string
--> non_unicode_env.rs:11:13
|
11 | let _ = option_env!(var_named_via_macro!());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors
2 changes: 1 addition & 1 deletion tests/ui/macros/builtin-env-issue-114010.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ env![r#"oopsie"#];
//~^ ERROR environment variable `oopsie` not defined at compile time

env![r#"a""a"#];
//~^ ERROR environment variable `a""a` not defined at compile time
//~^ ERROR environment variable `a\"\"a` not defined at compile time

fn main() {}
2 changes: 1 addition & 1 deletion tests/ui/macros/builtin-env-issue-114010.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LL | env![r#"oopsie"#];
|
= help: use `std::env::var(r#"oopsie"#)` to read the variable at run time

error: environment variable `a""a` not defined at compile time
error: environment variable `a\"\"a` not defined at compile time
--> $DIR/builtin-env-issue-114010.rs:7:1
|
LL | env![r#"a""a"#];
Expand Down
Loading