From 34e97592f4dc8f4e44a309e3bf69cdcea22fc047 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 8 Apr 2025 12:23:01 +1000 Subject: [PATCH] compiletest: Trim whitespace from environment variable names --- src/tools/compiletest/src/header.rs | 21 ++++++++--------- src/tools/compiletest/src/runtest.rs | 8 +++---- .../ui/compiletest-self-test/trim-env-name.rs | 23 +++++++++++++++++++ 3 files changed, 36 insertions(+), 16 deletions(-) create mode 100644 tests/ui/compiletest-self-test/trim-env-name.rs diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index a0178f4bcc576..e3adbb66dd9e3 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -441,7 +441,7 @@ impl TestProps { ln, UNSET_EXEC_ENV, &mut self.unset_exec_env, - |r| r, + |r| r.trim().to_owned(), ); config.push_name_value_directive( ln, @@ -453,7 +453,7 @@ impl TestProps { ln, UNSET_RUSTC_ENV, &mut self.unset_rustc_env, - |r| r, + |r| r.trim().to_owned(), ); config.push_name_value_directive( ln, @@ -979,16 +979,13 @@ impl Config { fn parse_env(nv: String) -> (String, String) { // nv is either FOO or FOO=BAR - let mut strs: Vec = nv.splitn(2, '=').map(str::to_owned).collect(); - - match strs.len() { - 1 => (strs.pop().unwrap(), String::new()), - 2 => { - let end = strs.pop().unwrap(); - (strs.pop().unwrap(), end) - } - n => panic!("Expected 1 or 2 strings, not {}", n), - } + // FIXME(Zalathar): The form without `=` seems to be unused; should + // we drop support for it? + let (name, value) = nv.split_once('=').unwrap_or((&nv, "")); + // Trim whitespace from the name, so that `//@ exec-env: FOO=BAR` + // sees the name as `FOO` and not ` FOO`. + let name = name.trim(); + (name.to_owned(), value.to_owned()) } fn parse_pp_exact(&self, line: &str, testfile: &Path) -> Option { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index c8a60b68da8b2..70d07b5f13232 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -971,16 +971,16 @@ impl<'test> TestCx<'test> { delete_after_success: bool, ) -> ProcRes { let prepare_env = |cmd: &mut Command| { - for key in &self.props.unset_exec_env { - cmd.env_remove(key); - } - for (key, val) in &self.props.exec_env { cmd.env(key, val); } for (key, val) in env_extra { cmd.env(key, val); } + + for key in &self.props.unset_exec_env { + cmd.env_remove(key); + } }; let proc_res = match &*self.config.target { diff --git a/tests/ui/compiletest-self-test/trim-env-name.rs b/tests/ui/compiletest-self-test/trim-env-name.rs new file mode 100644 index 0000000000000..0cb6efe9f7658 --- /dev/null +++ b/tests/ui/compiletest-self-test/trim-env-name.rs @@ -0,0 +1,23 @@ +//@ edition: 2024 +//@ revisions: set unset +//@ run-pass +//@ ignore-cross-compile (assume that non-cross targets have working env vars) +//@ rustc-env: MY_RUSTC_ENV = my-rustc-value +//@ exec-env: MY_EXEC_ENV = my-exec-value +//@[unset] unset-rustc-env: MY_RUSTC_ENV +//@[unset] unset-exec-env: MY_EXEC_ENV + +// Check that compiletest trims whitespace from environment variable names +// specified in `rustc-env` and `exec-env` directives, so that +// `//@ exec-env: FOO=bar` sees the name as `FOO` and not ` FOO`. +// +// Values are currently not trimmed. +// +// Since this is a compiletest self-test, only run it on non-cross targets, +// to avoid having to worry about weird targets that don't support env vars. + +fn main() { + let is_set = cfg!(set); + assert_eq!(option_env!("MY_RUSTC_ENV"), is_set.then_some(" my-rustc-value")); + assert_eq!(std::env::var("MY_EXEC_ENV").ok().as_deref(), is_set.then_some(" my-exec-value")); +}