Skip to content

Commit

Permalink
Make RUSTC_BOOTSTRAP read the crate name from CARGO_CRATE_NAME
Browse files Browse the repository at this point in the history
  • Loading branch information
Zalathar committed Nov 19, 2024
1 parent 94e71bf commit d47b57b
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 47 deletions.
10 changes: 4 additions & 6 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1211,9 +1211,7 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
if args.is_empty() {
// user did not write `-v` nor `-Z unstable-options`, so do not
// include that extra information.
let nightly_build =
rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build();
usage(false, false, nightly_build);
usage(false, false, nightly_options::is_nightly_build());
return None;
}

Expand Down Expand Up @@ -1265,7 +1263,7 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
if matches.opt_present("h") || matches.opt_present("help") {
// Only show unstable options in --help if we accept unstable options.
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
let nightly_build = nightly_options::match_is_nightly_build(&matches);
let nightly_build = nightly_options::is_nightly_build();
usage(matches.opt_present("verbose"), unstable_enabled, nightly_build);
return None;
}
Expand Down Expand Up @@ -1337,7 +1335,7 @@ fn ice_path_with_config(config: Option<&UnstableOptions>) -> &'static Option<Pat
}

ICE_PATH.get_or_init(|| {
if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
if !nightly_options::is_nightly_build() {
return None;
}
let mut path = match std::env::var_os("RUSTC_ICE") {
Expand Down Expand Up @@ -1493,7 +1491,7 @@ fn report_ice(
dcx.emit_note(session_diagnostics::IceBugReport { bug_report_url });

// Only emit update nightly hint for users on nightly builds.
if rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
if nightly_options::is_nightly_build() {
dcx.emit_note(session_diagnostics::UpdateNightlyNote);
}
}
Expand Down
60 changes: 37 additions & 23 deletions compiler/rustc_feature/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,38 +64,52 @@ pub enum UnstableFeatures {
}

impl UnstableFeatures {
/// 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_inner(krate, |name| env::var(name))
/// Determines whether this compiler allows unstable options/features,
/// according to whether it was built as a stable/beta compiler or a nightly
/// compiler, and taking `RUSTC_BOOTSTRAP` into account.
#[inline(never)]
pub fn from_environment() -> Self {
Self::from_environment_inner(|name| env::var(name))
}

/// Unit tests can pass a mock `std::env::var` instead of modifying the real environment.
fn from_environment_inner(
krate: Option<&str>,
env_var: impl Fn(&str) -> Result<String, env::VarError>, // std::env::var
) -> Self {
// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
// If `CFG_DISABLE_UNSTABLE_FEATURES` was true when this compiler was
// built, it is a stable/beta compiler that forbids unstable features.
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));

let bootstrap = env_var("RUSTC_BOOTSTRAP").ok();
if let Some(val) = bootstrap.as_deref() {
match val {
val if val == "1" || is_unstable_crate(val) => return UnstableFeatures::Cheat,
// Hypnotize ourselves so that we think we are a stable compiler and thus don't
// allow any unstable features.
"-1" => return UnstableFeatures::Disallow,
_ => {}
}
let default_answer = if disable_unstable_features {
UnstableFeatures::Disallow
} else {
UnstableFeatures::Allow
};

// Returns true if the given list of comma-separated crate names
// contains `CARGO_CRATE_NAME`.
//
// This is not actually used by bootstrap; it only exists so that when
// cargo sees a third-party crate trying to set `RUSTC_BOOTSTRAP=1` in
// build.rs, it can suggest a somewhat less horrifying alternative.
//
// See <https://github.com/rust-lang/rust/pull/77802> for context.
let includes_current_crate = |names: &str| -> bool {
let Ok(crate_name) = env_var("CARGO_CRATE_NAME") else { return false };
// Normalize `-` in crate names to `_`.
let crate_name = crate_name.replace('-', "_");
names.replace('-', "_").split(',').any(|name| name == crate_name)
};

match env_var("RUSTC_BOOTSTRAP").as_deref() {
// Force the compiler to act as nightly, even if it's stable.
Ok("1") => UnstableFeatures::Cheat,
// Force the compiler to act as stable, even if it's nightly.
Ok("-1") => UnstableFeatures::Disallow,
// Force nightly if `RUSTC_BOOTSTRAP` contains the current crate name.
Ok(names) if includes_current_crate(names) => UnstableFeatures::Cheat,
_ => default_answer,
}

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

pub fn is_nightly_build(&self) -> bool {
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_feature/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use std::env;
use super::UnstableFeatures;

fn unstable_features(rustc_bootstrap: &str, crate_name: Option<&str>) -> UnstableFeatures {
UnstableFeatures::from_environment_inner(crate_name, |name| match name {
UnstableFeatures::from_environment_inner(|name| match name {
"RUSTC_BOOTSTRAP" => Ok(rustc_bootstrap.to_owned()),
"CARGO_CRATE_NAME" => crate_name.map(str::to_owned).ok_or(env::VarError::NotPresent),
_ => Err(env::VarError::NotPresent),
})
}
Expand All @@ -21,6 +22,7 @@ fn rustc_bootstrap_parsing() {
// RUSTC_BOOTSTRAP allows multiple comma-delimited crates
assert!(is_bootstrap("x,y,z", Some("x")));
assert!(is_bootstrap("x,y,z", Some("y")));
assert!(is_bootstrap("x,y-utils", Some("y_utils")));
// Crate that aren't specified do not get unstable features
assert!(!is_bootstrap("x", Some("a")));
assert!(!is_bootstrap("x,y,z", Some("a")));
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1825,7 +1825,7 @@ pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches
};

if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) {
let is_nightly = nightly_options::match_is_nightly_build(matches);
let is_nightly = nightly_options::is_nightly_build();
let msg = if !is_nightly {
format!(
"the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
Expand Down Expand Up @@ -2510,7 +2510,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
let debuginfo_compression = unstable_opts.debuginfo_compression;

let crate_name = matches.opt_str("crate-name");
let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
let unstable_features = UnstableFeatures::from_environment();
// Parse any `-l` flags, which link to native libraries.
let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches);

Expand Down
13 changes: 4 additions & 9 deletions compiler/rustc_session/src/config/nightly_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@ use crate::EarlyDiagCtxt;
use crate::config::{OptionStability, RustcOptGroup};

pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
match_is_nightly_build(matches)
&& matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
is_nightly_build() && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
}

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

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

pub fn check_nightly_options(
Expand All @@ -22,7 +17,7 @@ pub fn check_nightly_options(
flags: &[RustcOptGroup],
) {
let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
let really_allows_unstable_options = match_is_nightly_build(matches);
let really_allows_unstable_options = is_nightly_build();
let mut nightly_options_on_stable = 0;

for opt in flags.iter() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ impl ParseSess {
pub fn with_dcx(dcx: DiagCtxt, source_map: Lrc<SourceMap>) -> Self {
Self {
dcx,
unstable_features: UnstableFeatures::from_environment(None),
unstable_features: UnstableFeatures::from_environment(),
config: Cfg::default(),
check_config: CheckCfg::default(),
edition: ExpnId::root().expn_data().edition,
Expand Down
7 changes: 3 additions & 4 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ impl Options {
println_condition(p.condition);
}

if nightly_options::match_is_nightly_build(matches) {
if nightly_options::is_nightly_build() {
println!("\nPasses run with `--show-coverage`:");
for p in passes::COVERAGE_PASSES {
print!("{:>20}", p.pass.name);
Expand Down Expand Up @@ -653,7 +653,7 @@ impl Options {
&matches.opt_strs("html-after-content"),
&matches.opt_strs("markdown-before-content"),
&matches.opt_strs("markdown-after-content"),
nightly_options::match_is_nightly_build(matches),
nightly_options::is_nightly_build(),
dcx,
&mut id_map,
edition,
Expand Down Expand Up @@ -775,8 +775,7 @@ impl Options {
let with_examples = matches.opt_strs("with-examples");
let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx);

let unstable_features =
rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
let unstable_features = rustc_feature::UnstableFeatures::from_environment();
let options = Options {
bin_crate,
proc_macro_crate,
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ pub(crate) fn create_config(
cg: codegen_options,
externs,
target_triple: target,
unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
unstable_features: UnstableFeatures::from_environment(),
actually_rustdoc: true,
resolve_doc_links,
unstable_opts,
Expand Down

0 comments on commit d47b57b

Please sign in to comment.