Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions compiler/rustc_feature/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,20 @@ pub enum UnstableFeatures {
}

impl UnstableFeatures {
/// This takes into account `RUSTC_BOOTSTRAP` and whether the input is in the sysroot.
///
/// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly
/// features. Otherwise, only `RUSTC_BOOTSTRAP=1` or `input_in_sysroot` will work.
pub fn from_environment_check_in_sysroot(krate: Option<&str>, input_in_sysroot: bool) -> Self {
Self::from_environment_value(krate, std::env::var("RUSTC_BOOTSTRAP"), input_in_sysroot)
}

/// This takes into account `RUSTC_BOOTSTRAP`.
///
/// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly
/// features. Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
pub fn from_environment(krate: Option<&str>) -> Self {
Self::from_environment_value(krate, std::env::var("RUSTC_BOOTSTRAP"))
Self::from_environment_value(krate, std::env::var("RUSTC_BOOTSTRAP"), false)
}

/// Avoid unsafe `std::env::set_var()` by allowing tests to inject
Expand All @@ -62,10 +70,8 @@ impl UnstableFeatures {
fn from_environment_value(
krate: Option<&str>,
env_var_rustc_bootstrap: Result<String, std::env::VarError>,
input_in_sysroot: bool,
) -> Self {
// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
let disable_unstable_features =
option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0");
// Returns whether `krate` should be counted as unstable
let is_unstable_crate =
|var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name));
Expand All @@ -81,6 +87,14 @@ impl UnstableFeatures {
}
}

if input_in_sysroot {
return UnstableFeatures::Cheat;
}

// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
let disable_unstable_features =
option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0");

if disable_unstable_features { UnstableFeatures::Disallow } else { UnstableFeatures::Allow }
}

Expand Down
16 changes: 14 additions & 2 deletions compiler/rustc_feature/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::UnstableFeatures;
fn rustc_bootstrap_parsing() {
let is_bootstrap = |env: &str, krate: Option<&str>| {
matches!(
UnstableFeatures::from_environment_value(krate, Ok(env.to_string())),
UnstableFeatures::from_environment_value(krate, Ok(env.to_string()), false),
UnstableFeatures::Cheat
)
};
Expand All @@ -23,10 +23,22 @@ fn rustc_bootstrap_parsing() {
// `RUSTC_BOOTSTRAP=0` is not recognized.
assert!(!is_bootstrap("0", None));

let is_bootstrap = |env: &str, krate: Option<&str>, input_in_sysroot: bool| {
matches!(
UnstableFeatures::from_environment_value(krate, Ok(env.to_string()), input_in_sysroot),
UnstableFeatures::Cheat
)
};
// Whether RUSTC_BOOTSTRAP is set or unset, when input_in_sysroot is_bootstrap should be true
assert!(is_bootstrap("1", None, true));
assert!(is_bootstrap("0", None, true));
// Even when input_in_sysroot, disabling RUSTC_BOOTSTRAP is honoured.
assert!(!is_bootstrap("-1", None, true));

// `RUSTC_BOOTSTRAP=-1` is force-stable, no unstable features allowed.
let is_force_stable = |krate: Option<&str>| {
matches!(
UnstableFeatures::from_environment_value(krate, Ok("-1".to_string())),
UnstableFeatures::from_environment_value(krate, Ok("-1".to_string()), false),
UnstableFeatures::Disallow
)
};
Expand Down
32 changes: 26 additions & 6 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::collections::btree_map::{
use std::collections::{BTreeMap, BTreeSet};
use std::ffi::OsStr;
use std::hash::Hash;
use std::path::{Path, PathBuf};
use std::path::{Path, PathBuf, absolute};
use std::str::{self, FromStr};
use std::sync::LazyLock;
use std::{cmp, fmt, fs, iter};
Expand Down Expand Up @@ -2434,7 +2434,10 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
let edition = parse_crate_edition(early_dcx, matches);

let crate_name = matches.opt_str("crate-name");
let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
let unstable_features = UnstableFeatures::from_environment_check_in_sysroot(
crate_name.as_deref(),
input_in_sysroot(matches),
);
let JsonConfig {
json_rendered,
json_color,
Expand Down Expand Up @@ -2863,10 +2866,26 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
Ok(crate_types)
}

pub fn input_in_sysroot(matches: &getopts::Matches) -> bool {
let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
// Input parsing derived from the make_input function. If there are multiple files, or stdin input, then
// input_in_sysroot is either irrelevant, or false.
let Some((Ok(input), Ok(sysroot))) = matches
.free
.as_slice()
.first()
.map(|path| (absolute(Path::new(path)), absolute(sysroot.path())))
else {
return false;
};

input.starts_with(sysroot)
}

pub mod nightly_options {
use rustc_feature::UnstableFeatures;

use super::{OptionStability, RustcOptGroup};
use super::{OptionStability, RustcOptGroup, input_in_sysroot};
use crate::EarlyDiagCtxt;

pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
Expand All @@ -2875,11 +2894,12 @@ pub mod nightly_options {
}

pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
is_nightly_build(matches.opt_str("crate-name").as_deref())
is_nightly_build(matches.opt_str("crate-name").as_deref(), input_in_sysroot(matches))
}

fn is_nightly_build(krate: Option<&str>) -> bool {
UnstableFeatures::from_environment(krate).is_nightly_build()
fn is_nightly_build(krate: Option<&str>, input_in_sysroot: bool) -> bool {
UnstableFeatures::from_environment_check_in_sysroot(krate, input_in_sysroot)
.is_nightly_build()
}

pub fn check_nightly_options(
Expand Down
Loading