1
Fork 0

Rollup merge of #135245 - Enselic:no-set-env, r=davidtwco

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.

Part of https://github.com/rust-lang/rust/issues/130672

Discussed at https://github.com/rust-lang/rust/pull/129636#discussion_r1766381501 (CC `@compiler-errors` `@bjorn3)`
This commit is contained in:
Matthias Krüger 2025-01-13 15:57:03 +01:00 committed by GitHub
commit 957247d546
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
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.