Skip to content

Commit 94e71bf

Browse files
committed
Don't modify the actual environment in RUSTC_BOOTSTRAP unit tests
Modifying process-global state in unit tests is bad news, because it can affect other unit tests running in parallel in the same process.
1 parent dddc174 commit 94e71bf

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

compiler/rustc_feature/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ mod unstable;
2626
#[cfg(test)]
2727
mod tests;
2828

29+
use std::env;
2930
use std::num::NonZero;
3031

3132
use rustc_span::symbol::Symbol;
@@ -68,14 +69,22 @@ impl UnstableFeatures {
6869
/// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly
6970
/// features. Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
7071
pub fn from_environment(krate: Option<&str>) -> Self {
72+
Self::from_environment_inner(krate, |name| env::var(name))
73+
}
74+
75+
/// Unit tests can pass a mock `std::env::var` instead of modifying the real environment.
76+
fn from_environment_inner(
77+
krate: Option<&str>,
78+
env_var: impl Fn(&str) -> Result<String, env::VarError>, // std::env::var
79+
) -> Self {
7180
// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
7281
let disable_unstable_features =
7382
option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0");
7483
// Returns whether `krate` should be counted as unstable
7584
let is_unstable_crate =
7685
|var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name));
7786

78-
let bootstrap = std::env::var("RUSTC_BOOTSTRAP").ok();
87+
let bootstrap = env_var("RUSTC_BOOTSTRAP").ok();
7988
if let Some(val) = bootstrap.as_deref() {
8089
match val {
8190
val if val == "1" || is_unstable_crate(val) => return UnstableFeatures::Cheat,

compiler/rustc_feature/src/tests.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1+
use std::env;
2+
13
use super::UnstableFeatures;
24

5+
fn unstable_features(rustc_bootstrap: &str, crate_name: Option<&str>) -> UnstableFeatures {
6+
UnstableFeatures::from_environment_inner(crate_name, |name| match name {
7+
"RUSTC_BOOTSTRAP" => Ok(rustc_bootstrap.to_owned()),
8+
_ => Err(env::VarError::NotPresent),
9+
})
10+
}
11+
312
#[test]
413
fn rustc_bootstrap_parsing() {
5-
let is_bootstrap = |env, krate| {
6-
std::env::set_var("RUSTC_BOOTSTRAP", env);
7-
matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Cheat)
14+
let is_bootstrap = |rustc_bootstrap, crate_name| {
15+
matches!(unstable_features(rustc_bootstrap, crate_name), UnstableFeatures::Cheat)
816
};
917
assert!(is_bootstrap("1", None));
1018
assert!(is_bootstrap("1", Some("x")));
@@ -22,10 +30,8 @@ fn rustc_bootstrap_parsing() {
2230
assert!(!is_bootstrap("0", None));
2331

2432
// `RUSTC_BOOTSTRAP=-1` is force-stable, no unstable features allowed.
25-
let is_force_stable = |krate| {
26-
std::env::set_var("RUSTC_BOOTSTRAP", "-1");
27-
matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Disallow)
28-
};
33+
let is_force_stable =
34+
|crate_name| matches!(unstable_features("-1", crate_name), UnstableFeatures::Disallow);
2935
assert!(is_force_stable(None));
3036
// Does not support specifying any crate.
3137
assert!(is_force_stable(Some("x")));

0 commit comments

Comments
 (0)