1
Fork 0

rustc_feature: Avoid unsafe std::env::set_var() in UnstableFeatures tests

Avoid unsafe `std::env::set_var()` by allowing tests to inject
`std::env::var("RUSTC_BOOTSTRAP")` with a `env_var_rustc_bootstrap`
parameter.
This commit is contained in:
Martin Nordholts 2025-01-08 11:34:39 +01:00
parent 9c87288a7d
commit 54ce831db0
2 changed files with 21 additions and 7 deletions

View file

@ -68,6 +68,16 @@ impl UnstableFeatures {
/// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly /// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly
/// features. Otherwise, only `RUSTC_BOOTSTRAP=1` will work. /// features. Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
pub fn from_environment(krate: Option<&str>) -> Self { pub fn from_environment(krate: Option<&str>) -> Self {
Self::from_environment_value(krate, std::env::var("RUSTC_BOOTSTRAP"))
}
/// Avoid unsafe `std::env::set_var()` by allowing tests to inject
/// `std::env::var("RUSTC_BOOTSTRAP")` with the `env_var_rustc_bootstrap`
/// arg.
fn from_environment_value(
krate: Option<&str>,
env_var_rustc_bootstrap: Result<String, std::env::VarError>,
) -> Self {
// `true` if this is a feature-staged build, i.e., on the beta or stable channel. // `true` if this is a feature-staged build, i.e., on the beta or stable channel.
let disable_unstable_features = let disable_unstable_features =
option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0"); option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0");
@ -75,7 +85,7 @@ impl UnstableFeatures {
let is_unstable_crate = let is_unstable_crate =
|var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name)); |var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name));
let bootstrap = std::env::var("RUSTC_BOOTSTRAP").ok(); let bootstrap = env_var_rustc_bootstrap.ok();
if let Some(val) = bootstrap.as_deref() { if let Some(val) = bootstrap.as_deref() {
match val { match val {
val if val == "1" || is_unstable_crate(val) => return UnstableFeatures::Cheat, val if val == "1" || is_unstable_crate(val) => return UnstableFeatures::Cheat,

View file

@ -2,9 +2,11 @@ use super::UnstableFeatures;
#[test] #[test]
fn rustc_bootstrap_parsing() { fn rustc_bootstrap_parsing() {
let is_bootstrap = |env, krate| { let is_bootstrap = |env: &str, krate: Option<&str>| {
std::env::set_var("RUSTC_BOOTSTRAP", env); matches!(
matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Cheat) UnstableFeatures::from_environment_value(krate, Ok(env.to_string())),
UnstableFeatures::Cheat
)
}; };
assert!(is_bootstrap("1", None)); assert!(is_bootstrap("1", None));
assert!(is_bootstrap("1", Some("x"))); assert!(is_bootstrap("1", Some("x")));
@ -22,9 +24,11 @@ fn rustc_bootstrap_parsing() {
assert!(!is_bootstrap("0", None)); assert!(!is_bootstrap("0", None));
// `RUSTC_BOOTSTRAP=-1` is force-stable, no unstable features allowed. // `RUSTC_BOOTSTRAP=-1` is force-stable, no unstable features allowed.
let is_force_stable = |krate| { let is_force_stable = |krate: Option<&str>| {
std::env::set_var("RUSTC_BOOTSTRAP", "-1"); matches!(
matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Disallow) UnstableFeatures::from_environment_value(krate, Ok("-1".to_string())),
UnstableFeatures::Disallow
)
}; };
assert!(is_force_stable(None)); assert!(is_force_stable(None));
// Does not support specifying any crate. // Does not support specifying any crate.