Skip to content

Commit d47b57b

Browse files
committed
Make RUSTC_BOOTSTRAP read the crate name from CARGO_CRATE_NAME
1 parent 94e71bf commit d47b57b

File tree

8 files changed

+55
-47
lines changed

8 files changed

+55
-47
lines changed

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,9 +1211,7 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
12111211
if args.is_empty() {
12121212
// user did not write `-v` nor `-Z unstable-options`, so do not
12131213
// include that extra information.
1214-
let nightly_build =
1215-
rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build();
1216-
usage(false, false, nightly_build);
1214+
usage(false, false, nightly_options::is_nightly_build());
12171215
return None;
12181216
}
12191217

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

13391337
ICE_PATH.get_or_init(|| {
1340-
if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
1338+
if !nightly_options::is_nightly_build() {
13411339
return None;
13421340
}
13431341
let mut path = match std::env::var_os("RUSTC_ICE") {
@@ -1493,7 +1491,7 @@ fn report_ice(
14931491
dcx.emit_note(session_diagnostics::IceBugReport { bug_report_url });
14941492

14951493
// Only emit update nightly hint for users on nightly builds.
1496-
if rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
1494+
if nightly_options::is_nightly_build() {
14971495
dcx.emit_note(session_diagnostics::UpdateNightlyNote);
14981496
}
14991497
}

compiler/rustc_feature/src/lib.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -64,38 +64,52 @@ pub enum UnstableFeatures {
6464
}
6565

6666
impl UnstableFeatures {
67-
/// This takes into account `RUSTC_BOOTSTRAP`.
68-
///
69-
/// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly
70-
/// features. Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
71-
pub fn from_environment(krate: Option<&str>) -> Self {
72-
Self::from_environment_inner(krate, |name| env::var(name))
67+
/// Determines whether this compiler allows unstable options/features,
68+
/// according to whether it was built as a stable/beta compiler or a nightly
69+
/// compiler, and taking `RUSTC_BOOTSTRAP` into account.
70+
#[inline(never)]
71+
pub fn from_environment() -> Self {
72+
Self::from_environment_inner(|name| env::var(name))
7373
}
7474

7575
/// Unit tests can pass a mock `std::env::var` instead of modifying the real environment.
7676
fn from_environment_inner(
77-
krate: Option<&str>,
7877
env_var: impl Fn(&str) -> Result<String, env::VarError>, // std::env::var
7978
) -> Self {
80-
// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
79+
// If `CFG_DISABLE_UNSTABLE_FEATURES` was true when this compiler was
80+
// built, it is a stable/beta compiler that forbids unstable features.
8181
let disable_unstable_features =
8282
option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0");
83-
// Returns whether `krate` should be counted as unstable
84-
let is_unstable_crate =
85-
|var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name));
86-
87-
let bootstrap = env_var("RUSTC_BOOTSTRAP").ok();
88-
if let Some(val) = bootstrap.as_deref() {
89-
match val {
90-
val if val == "1" || is_unstable_crate(val) => return UnstableFeatures::Cheat,
91-
// Hypnotize ourselves so that we think we are a stable compiler and thus don't
92-
// allow any unstable features.
93-
"-1" => return UnstableFeatures::Disallow,
94-
_ => {}
95-
}
83+
let default_answer = if disable_unstable_features {
84+
UnstableFeatures::Disallow
85+
} else {
86+
UnstableFeatures::Allow
87+
};
88+
89+
// Returns true if the given list of comma-separated crate names
90+
// contains `CARGO_CRATE_NAME`.
91+
//
92+
// This is not actually used by bootstrap; it only exists so that when
93+
// cargo sees a third-party crate trying to set `RUSTC_BOOTSTRAP=1` in
94+
// build.rs, it can suggest a somewhat less horrifying alternative.
95+
//
96+
// See <https://github.com/rust-lang/rust/pull/77802> for context.
97+
let includes_current_crate = |names: &str| -> bool {
98+
let Ok(crate_name) = env_var("CARGO_CRATE_NAME") else { return false };
99+
// Normalize `-` in crate names to `_`.
100+
let crate_name = crate_name.replace('-', "_");
101+
names.replace('-', "_").split(',').any(|name| name == crate_name)
102+
};
103+
104+
match env_var("RUSTC_BOOTSTRAP").as_deref() {
105+
// Force the compiler to act as nightly, even if it's stable.
106+
Ok("1") => UnstableFeatures::Cheat,
107+
// Force the compiler to act as stable, even if it's nightly.
108+
Ok("-1") => UnstableFeatures::Disallow,
109+
// Force nightly if `RUSTC_BOOTSTRAP` contains the current crate name.
110+
Ok(names) if includes_current_crate(names) => UnstableFeatures::Cheat,
111+
_ => default_answer,
96112
}
97-
98-
if disable_unstable_features { UnstableFeatures::Disallow } else { UnstableFeatures::Allow }
99113
}
100114

101115
pub fn is_nightly_build(&self) -> bool {

compiler/rustc_feature/src/tests.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use std::env;
33
use super::UnstableFeatures;
44

55
fn unstable_features(rustc_bootstrap: &str, crate_name: Option<&str>) -> UnstableFeatures {
6-
UnstableFeatures::from_environment_inner(crate_name, |name| match name {
6+
UnstableFeatures::from_environment_inner(|name| match name {
77
"RUSTC_BOOTSTRAP" => Ok(rustc_bootstrap.to_owned()),
8+
"CARGO_CRATE_NAME" => crate_name.map(str::to_owned).ok_or(env::VarError::NotPresent),
89
_ => Err(env::VarError::NotPresent),
910
})
1011
}
@@ -21,6 +22,7 @@ fn rustc_bootstrap_parsing() {
2122
// RUSTC_BOOTSTRAP allows multiple comma-delimited crates
2223
assert!(is_bootstrap("x,y,z", Some("x")));
2324
assert!(is_bootstrap("x,y,z", Some("y")));
25+
assert!(is_bootstrap("x,y-utils", Some("y_utils")));
2426
// Crate that aren't specified do not get unstable features
2527
assert!(!is_bootstrap("x", Some("a")));
2628
assert!(!is_bootstrap("x,y,z", Some("a")));

compiler/rustc_session/src/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,7 +1825,7 @@ pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches
18251825
};
18261826

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

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

compiler/rustc_session/src/config/nightly_options.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,11 @@ use crate::EarlyDiagCtxt;
44
use crate::config::{OptionStability, RustcOptGroup};
55

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

11-
pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
12-
is_nightly_build(matches.opt_str("crate-name").as_deref())
13-
}
14-
15-
fn is_nightly_build(krate: Option<&str>) -> bool {
16-
UnstableFeatures::from_environment(krate).is_nightly_build()
10+
pub fn is_nightly_build() -> bool {
11+
UnstableFeatures::from_environment().is_nightly_build()
1712
}
1813

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

2823
for opt in flags.iter() {

compiler/rustc_session/src/parse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ impl ParseSess {
251251
pub fn with_dcx(dcx: DiagCtxt, source_map: Lrc<SourceMap>) -> Self {
252252
Self {
253253
dcx,
254-
unstable_features: UnstableFeatures::from_environment(None),
254+
unstable_features: UnstableFeatures::from_environment(),
255255
config: Cfg::default(),
256256
check_config: CheckCfg::default(),
257257
edition: ExpnId::root().expn_data().edition,

src/librustdoc/config.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ impl Options {
409409
println_condition(p.condition);
410410
}
411411

412-
if nightly_options::match_is_nightly_build(matches) {
412+
if nightly_options::is_nightly_build() {
413413
println!("\nPasses run with `--show-coverage`:");
414414
for p in passes::COVERAGE_PASSES {
415415
print!("{:>20}", p.pass.name);
@@ -653,7 +653,7 @@ impl Options {
653653
&matches.opt_strs("html-after-content"),
654654
&matches.opt_strs("markdown-before-content"),
655655
&matches.opt_strs("markdown-after-content"),
656-
nightly_options::match_is_nightly_build(matches),
656+
nightly_options::is_nightly_build(),
657657
dcx,
658658
&mut id_map,
659659
edition,
@@ -775,8 +775,7 @@ impl Options {
775775
let with_examples = matches.opt_strs("with-examples");
776776
let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx);
777777

778-
let unstable_features =
779-
rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
778+
let unstable_features = rustc_feature::UnstableFeatures::from_environment();
780779
let options = Options {
781780
bin_crate,
782781
proc_macro_crate,

src/librustdoc/core.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ pub(crate) fn create_config(
260260
cg: codegen_options,
261261
externs,
262262
target_triple: target,
263-
unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
263+
unstable_features: UnstableFeatures::from_environment(),
264264
actually_rustdoc: true,
265265
resolve_doc_links,
266266
unstable_opts,

0 commit comments

Comments
 (0)