Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explain compile-time vs run-time difference in env!() error message #108573

Merged
merged 1 commit into from
Mar 3, 2023
Merged
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
40 changes: 30 additions & 10 deletions compiler/rustc_builtin_macros/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn expand_env<'cx>(
tts: TokenStream,
) -> Box<dyn base::MacResult + 'cx> {
let mut exprs = match get_exprs_from_tts(cx, tts) {
Some(exprs) if exprs.is_empty() => {
Some(exprs) if exprs.is_empty() || exprs.len() > 2 => {
kornelski marked this conversation as resolved.
Show resolved Hide resolved
cx.span_err(sp, "env! takes 1 or 2 arguments");
return DummyResult::any(sp);
}
Expand All @@ -64,28 +64,48 @@ pub fn expand_env<'cx>(
let Some((var, _style)) = expr_to_string(cx, exprs.next().unwrap(), "expected string literal") else {
return DummyResult::any(sp);
};
let msg = match exprs.next() {
None => Symbol::intern(&format!("environment variable `{}` not defined", var)),

let custom_msg = match exprs.next() {
None => None,
Some(second) => match expr_to_string(cx, second, "expected string literal") {
None => return DummyResult::any(sp),
Some((s, _style)) => s,
Some((s, _style)) => Some(s),
},
};

if exprs.next().is_some() {
cx.span_err(sp, "env! takes 1 or 2 arguments");
return DummyResult::any(sp);
}

let sp = cx.with_def_site_ctxt(sp);
let value = env::var(var.as_str()).ok().as_deref().map(Symbol::intern);
cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value));
let e = match value {
None => {
cx.span_err(sp, msg.as_str());
let (msg, help) = match custom_msg {
None => (
format!("environment variable `{var}` not defined at compile time"),
Some(help_for_missing_env_var(var.as_str())),
),
Some(s) => (s.to_string(), None),
};
let mut diag = cx.struct_span_err(sp, &msg);
if let Some(help) = help {
diag.help(help);
}
diag.emit();
return DummyResult::any(sp);
}
Some(value) => cx.expr_str(sp, value),
};
MacEager::expr(e)
}

fn help_for_missing_env_var(var: &str) -> String {
if var.starts_with("CARGO_")
|| var.starts_with("DEP_")
|| matches!(var, "OUT_DIR" | "OPT_LEVEL" | "PROFILE" | "HOST" | "TARGET")
{
format!(
"Cargo sets build script variables at run time. Use `std::env::var(\"{var}\")` instead"
)
} else {
format!("Use `std::env::var(\"{var}\")` to read the variable at run time")
}
}
4 changes: 2 additions & 2 deletions tests/ui/extenv/extenv-not-defined-default.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn main() {
env!("__HOPEFULLY_NOT_DEFINED__");
//~^ ERROR: environment variable `__HOPEFULLY_NOT_DEFINED__` not defined
env!("CARGO__HOPEFULLY_NOT_DEFINED__");
//~^ ERROR: environment variable `CARGO__HOPEFULLY_NOT_DEFINED__` not defined
}
7 changes: 4 additions & 3 deletions tests/ui/extenv/extenv-not-defined-default.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
error: environment variable `__HOPEFULLY_NOT_DEFINED__` not defined
error: environment variable `CARGO__HOPEFULLY_NOT_DEFINED__` not defined at compile time
--> $DIR/extenv-not-defined-default.rs:2:5
|
LL | env!("__HOPEFULLY_NOT_DEFINED__");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | env!("CARGO__HOPEFULLY_NOT_DEFINED__");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: Cargo sets build script variables at run time. Use `std::env::var("CARGO__HOPEFULLY_NOT_DEFINED__")` instead
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/extenv/issue-55897.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
error: environment variable `NON_EXISTENT` not defined
error: environment variable `NON_EXISTENT` not defined at compile time
--> $DIR/issue-55897.rs:11:22
|
LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
| ^^^^^^^^^^^^^^^^^^^^
|
= help: Use `std::env::var("NON_EXISTENT")` to read the variable at run time
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)

error: suffixes on string literals are invalid
Expand Down
9 changes: 5 additions & 4 deletions tests/ui/macros/macros-nonfatal-errors.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,19 @@ error: expected string literal
LL | env!(invalid);
| ^^^^^^^

error: expected string literal
--> $DIR/macros-nonfatal-errors.rs:105:10
error: env! takes 1 or 2 arguments
--> $DIR/macros-nonfatal-errors.rs:105:5
|
LL | env!(foo, abr, baz);
| ^^^
| ^^^^^^^^^^^^^^^^^^^

error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined
error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined at compile time
--> $DIR/macros-nonfatal-errors.rs:106:5
|
LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: Use `std::env::var("RUST_HOPEFULLY_THIS_DOESNT_EXIST")` to read the variable at run time
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)

error: format argument must be a string literal
Expand Down