Skip to content

Commit 3abbdff

Browse files
committed
For "stage 1" ui-fulldeps, use the stage 1 compiler to query target info
Testing ui-fulldeps in "stage 1" actually uses the stage 0 compiler, so that test programs can link against stage 1 rustc crates. Unfortunately, using the stage 0 compiler causes problems when compiletest tries to obtain target information from the compiler, but the output format has changed since the last bootstrap beta bump. We can work around this by also providing compiletest with a stage 1 compiler, and having it use that compiler to query for target information.
1 parent 5b9564a commit 3abbdff

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

src/bootstrap/src/core/build_steps/test.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,7 +1663,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
16631663
// bootstrap compiler.
16641664
// NOTE: Only stage 1 is special cased because we need the rustc_private artifacts to match the
16651665
// running compiler in stage 2 when plugins run.
1666+
let query_compiler;
16661667
let (stage, stage_id) = if suite == "ui-fulldeps" && compiler.stage == 1 {
1668+
// Even when using the stage 0 compiler, we also need to provide the stage 1 compiler
1669+
// so that compiletest can query it for target information.
1670+
query_compiler = Some(compiler);
16671671
// At stage 0 (stage - 1) we are using the stage0 compiler. Using `self.target` can lead
16681672
// finding an incorrect compiler path on cross-targets, as the stage 0 is always equal to
16691673
// `build.build` in the configuration.
@@ -1672,6 +1676,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
16721676
let test_stage = compiler.stage + 1;
16731677
(test_stage, format!("stage{test_stage}-{build}"))
16741678
} else {
1679+
query_compiler = None;
16751680
let stage = compiler.stage;
16761681
(stage, format!("stage{stage}-{target}"))
16771682
};
@@ -1716,6 +1721,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
17161721
cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(compiler));
17171722
cmd.arg("--run-lib-path").arg(builder.sysroot_target_libdir(compiler, target));
17181723
cmd.arg("--rustc-path").arg(builder.rustc(compiler));
1724+
if let Some(query_compiler) = query_compiler {
1725+
cmd.arg("--query-rustc-path").arg(builder.rustc(query_compiler));
1726+
}
17191727

17201728
// Minicore auxiliary lib for `no_core` tests that need `core` stubs in cross-compilation
17211729
// scenarios.

src/tools/compiletest/src/common.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,15 @@ pub struct Config {
279279
/// [`Self::rustc_path`].
280280
pub stage0_rustc_path: Option<Utf8PathBuf>,
281281

282+
/// Path to the stage 1 or higher `rustc` used to obtain target information via
283+
/// `--print=all-target-specs-json` and similar queries.
284+
///
285+
/// Normally this is unset, because [`Self::rustc_path`] can be used instead.
286+
/// But when running "stage 1" ui-fulldeps tests, `rustc_path` is a stage 0
287+
/// compiler, whereas target specs must be obtained from a stage 1+ compiler
288+
/// (in case the JSON format has changed since the last bootstrap bump).
289+
pub query_rustc_path: Option<Utf8PathBuf>,
290+
282291
/// Path to the `rustdoc`-under-test. Like [`Self::rustc_path`], this `rustdoc` is *staged*.
283292
pub rustdoc_path: Option<Utf8PathBuf>,
284293

@@ -712,6 +721,7 @@ impl Config {
712721
rustc_path: Utf8PathBuf::default(),
713722
cargo_path: Default::default(),
714723
stage0_rustc_path: Default::default(),
724+
query_rustc_path: Default::default(),
715725
rustdoc_path: Default::default(),
716726
coverage_dump_path: Default::default(),
717727
python: Default::default(),
@@ -917,7 +927,7 @@ pub struct TargetCfgs {
917927

918928
impl TargetCfgs {
919929
fn new(config: &Config) -> TargetCfgs {
920-
let mut targets: HashMap<String, TargetCfg> = serde_json::from_str(&rustc_output(
930+
let mut targets: HashMap<String, TargetCfg> = serde_json::from_str(&query_rustc_output(
921931
config,
922932
&["--print=all-target-specs-json", "-Zunstable-options"],
923933
Default::default(),
@@ -950,7 +960,7 @@ impl TargetCfgs {
950960
if config.target.ends_with(".json") || !envs.is_empty() {
951961
targets.insert(
952962
config.target.clone(),
953-
serde_json::from_str(&rustc_output(
963+
serde_json::from_str(&query_rustc_output(
954964
config,
955965
&[
956966
"--print=target-spec-json",
@@ -1009,10 +1019,13 @@ impl TargetCfgs {
10091019
// which are respected for `--print=cfg` but not for `--print=all-target-specs-json`. The
10101020
// code below extracts them from `--print=cfg`: make sure to only override fields that can
10111021
// actually be changed with `-C` flags.
1012-
for config in
1013-
rustc_output(config, &["--print=cfg", "--target", &config.target], Default::default())
1014-
.trim()
1015-
.lines()
1022+
for config in query_rustc_output(
1023+
config,
1024+
&["--print=cfg", "--target", &config.target],
1025+
Default::default(),
1026+
)
1027+
.trim()
1028+
.lines()
10161029
{
10171030
let (name, value) = config
10181031
.split_once("=\"")
@@ -1113,7 +1126,7 @@ pub enum Endian {
11131126
}
11141127

11151128
fn builtin_cfg_names(config: &Config) -> HashSet<String> {
1116-
rustc_output(
1129+
query_rustc_output(
11171130
config,
11181131
&["--print=check-cfg", "-Zunstable-options", "--check-cfg=cfg()"],
11191132
Default::default(),
@@ -1128,7 +1141,7 @@ pub const KNOWN_CRATE_TYPES: &[&str] =
11281141
&["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
11291142

11301143
fn supported_crate_types(config: &Config) -> HashSet<String> {
1131-
let crate_types: HashSet<_> = rustc_output(
1144+
let crate_types: HashSet<_> = query_rustc_output(
11321145
config,
11331146
&["--target", &config.target, "--print=supported-crate-types", "-Zunstable-options"],
11341147
Default::default(),
@@ -1149,8 +1162,10 @@ fn supported_crate_types(config: &Config) -> HashSet<String> {
11491162
crate_types
11501163
}
11511164

1152-
fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
1153-
let mut command = Command::new(&config.rustc_path);
1165+
fn query_rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
1166+
let query_rustc_path = config.query_rustc_path.as_deref().unwrap_or(&config.rustc_path);
1167+
1168+
let mut command = Command::new(query_rustc_path);
11541169
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
11551170
command.args(&config.target_rustcflags).args(args);
11561171
command.env("RUSTC_BOOTSTRAP", "1");

src/tools/compiletest/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
6363
"path to rustc to use for compiling run-make recipes",
6464
"PATH",
6565
)
66+
.optopt(
67+
"",
68+
"query-rustc-path",
69+
"path to rustc to use for querying target information (defaults to `--rustc-path`)",
70+
"PATH",
71+
)
6672
.optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH")
6773
.optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH")
6874
.reqopt("", "python", "path to python to use for doc tests", "PATH")
@@ -354,6 +360,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
354360
rustc_path: opt_path(matches, "rustc-path"),
355361
cargo_path: matches.opt_str("cargo-path").map(Utf8PathBuf::from),
356362
stage0_rustc_path: matches.opt_str("stage0-rustc-path").map(Utf8PathBuf::from),
363+
query_rustc_path: matches.opt_str("query-rustc-path").map(Utf8PathBuf::from),
357364
rustdoc_path: matches.opt_str("rustdoc-path").map(Utf8PathBuf::from),
358365
coverage_dump_path: matches.opt_str("coverage-dump-path").map(Utf8PathBuf::from),
359366
python: matches.opt_str("python").unwrap(),

0 commit comments

Comments
 (0)