Skip to content

Commit 6b40b1d

Browse files
committed
Auto merge of rust-lang#139507 - Zalathar:trim-env-name, r=<try>
compiletest: Trim whitespace from environment variable names When a test contains a directive like `//@ exec-env: FOO=bar`, compiletest currently includes that leading space in the name of the environment variable, so it is defined as ` FOO` instead of `FOO`. This is an annoying footgun that is pretty much never intended, especially since most other directives *do* trim whitespace. So let's get rid of it by trimming the environment variable name. Values remain untrimmed, since there could conceivably be a use-case for values with leading space, but perhaps we'll end up trimming values too in the future. Recently observed in rust-lang#138603 (comment). Fixes rust-lang#132990. Supersedes rust-lang#133148. --- try-job: test-various
2 parents c6c1796 + 21851a0 commit 6b40b1d

File tree

6 files changed

+40
-10
lines changed

6 files changed

+40
-10
lines changed

src/doc/rustc-dev-guide/src/tests/directives.md

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ settings:
158158

159159
- `needs-asm-support` — ignores if it is running on a target that doesn't have
160160
stable support for `asm!`
161+
- `needs-env-vars` - ignores if the target doesn't support environment variables
161162
- `needs-profiler-runtime` — ignores the test if the profiler runtime was not
162163
enabled for the target
163164
(`build.profiler = true` in rustc's `bootstrap.toml`)

src/tools/compiletest/src/common.rs

+10
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,16 @@ impl Config {
520520
|| self.target_cfg().os == "emscripten";
521521
!unsupported_target
522522
}
523+
524+
pub fn has_env_vars(&self) -> bool {
525+
// As with some of the other target properties, we don't have a principled
526+
// way to know whether the target supports environment variables, so we
527+
// just hard-code a reasonable approximation.
528+
529+
let target = self.target_cfg();
530+
let no_env = matches!(target.arch.as_str(), "wasm32" | "wasm64") && target.os == "unknown";
531+
!no_env
532+
}
523533
}
524534

525535
/// Known widths of `target_has_atomic`.

src/tools/compiletest/src/directive-list.rs

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
135135
"needs-deterministic-layouts",
136136
"needs-dlltool",
137137
"needs-dynamic-linking",
138+
"needs-env-vars",
138139
"needs-enzyme",
139140
"needs-force-clang-based-tests",
140141
"needs-git-hash",

src/tools/compiletest/src/header.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -979,16 +979,13 @@ impl Config {
979979

980980
fn parse_env(nv: String) -> (String, String) {
981981
// nv is either FOO or FOO=BAR
982-
let mut strs: Vec<String> = nv.splitn(2, '=').map(str::to_owned).collect();
983-
984-
match strs.len() {
985-
1 => (strs.pop().unwrap(), String::new()),
986-
2 => {
987-
let end = strs.pop().unwrap();
988-
(strs.pop().unwrap(), end)
989-
}
990-
n => panic!("Expected 1 or 2 strings, not {}", n),
991-
}
982+
// FIXME(Zalathar): The form without `=` seems to be unused; should
983+
// we drop support for it?
984+
let (name, value) = nv.split_once('=').unwrap_or((&nv, ""));
985+
// Trim whitespace from the name, so that `//@ exec-env: FOO=BAR`
986+
// sees the name as `FOO` and not ` FOO`.
987+
let name = name.trim();
988+
(name.to_owned(), value.to_owned())
992989
}
993990

994991
fn parse_pp_exact(&self, line: &str, testfile: &Path) -> Option<PathBuf> {

src/tools/compiletest/src/header/needs.rs

+5
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ pub(super) fn handle_needs(
174174
condition: config.with_std_debug_assertions,
175175
ignore_reason: "ignored if std wasn't built with debug assertions",
176176
},
177+
Need {
178+
name: "needs-env-vars",
179+
condition: config.has_env_vars(),
180+
ignore_reason: "ignored on targets without environment variables",
181+
},
177182
];
178183

179184
let (name, rest) = match ln.split_once([':', ' ']) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//@ edition: 2024
2+
//@ run-pass
3+
//@ needs-env-vars
4+
//@ rustc-env: MY_RUSTC_ENV = my-rustc-value
5+
//@ exec-env: MY_EXEC_ENV = my-exec-value
6+
7+
// Check that compiletest trims whitespace from environment variable names
8+
// specified in `rustc-env` and `exec-env` directives, so that
9+
// `//@ exec-env: FOO=bar` sees the name as `FOO` and not ` FOO`.
10+
//
11+
// Values are currently not trimmed.
12+
13+
fn main() {
14+
assert_eq!(option_env!("MY_RUSTC_ENV"), Some(" my-rustc-value"));
15+
assert_eq!(std::env::var("MY_EXEC_ENV").as_deref(), Ok(" my-exec-value"));
16+
}

0 commit comments

Comments
 (0)