diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index ffc5dfad459db..8bee00a9c1376 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1663,7 +1663,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // bootstrap compiler. // NOTE: Only stage 1 is special cased because we need the rustc_private artifacts to match the // running compiler in stage 2 when plugins run. + let query_compiler; let (stage, stage_id) = if suite == "ui-fulldeps" && compiler.stage == 1 { + // Even when using the stage 0 compiler, we also need to provide the stage 1 compiler + // so that compiletest can query it for target information. + query_compiler = Some(compiler); // At stage 0 (stage - 1) we are using the stage0 compiler. Using `self.target` can lead // finding an incorrect compiler path on cross-targets, as the stage 0 is always equal to // `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 let test_stage = compiler.stage + 1; (test_stage, format!("stage{test_stage}-{build}")) } else { + query_compiler = None; let stage = compiler.stage; (stage, format!("stage{stage}-{target}")) }; @@ -1716,6 +1721,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(compiler)); cmd.arg("--run-lib-path").arg(builder.sysroot_target_libdir(compiler, target)); cmd.arg("--rustc-path").arg(builder.rustc(compiler)); + if let Some(query_compiler) = query_compiler { + cmd.arg("--query-rustc-path").arg(builder.rustc(query_compiler)); + } // Minicore auxiliary lib for `no_core` tests that need `core` stubs in cross-compilation // scenarios. diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index aceae3e3a3b9c..2d49b1a7097d0 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -279,6 +279,15 @@ pub struct Config { /// [`Self::rustc_path`]. pub stage0_rustc_path: Option, + /// Path to the stage 1 or higher `rustc` used to obtain target information via + /// `--print=all-target-specs-json` and similar queries. + /// + /// Normally this is unset, because [`Self::rustc_path`] can be used instead. + /// But when running "stage 1" ui-fulldeps tests, `rustc_path` is a stage 0 + /// compiler, whereas target specs must be obtained from a stage 1+ compiler + /// (in case the JSON format has changed since the last bootstrap bump). + pub query_rustc_path: Option, + /// Path to the `rustdoc`-under-test. Like [`Self::rustc_path`], this `rustdoc` is *staged*. pub rustdoc_path: Option, @@ -712,6 +721,7 @@ impl Config { rustc_path: Utf8PathBuf::default(), cargo_path: Default::default(), stage0_rustc_path: Default::default(), + query_rustc_path: Default::default(), rustdoc_path: Default::default(), coverage_dump_path: Default::default(), python: Default::default(), @@ -917,7 +927,7 @@ pub struct TargetCfgs { impl TargetCfgs { fn new(config: &Config) -> TargetCfgs { - let mut targets: HashMap = serde_json::from_str(&rustc_output( + let mut targets: HashMap = serde_json::from_str(&query_rustc_output( config, &["--print=all-target-specs-json", "-Zunstable-options"], Default::default(), @@ -950,7 +960,7 @@ impl TargetCfgs { if config.target.ends_with(".json") || !envs.is_empty() { targets.insert( config.target.clone(), - serde_json::from_str(&rustc_output( + serde_json::from_str(&query_rustc_output( config, &[ "--print=target-spec-json", @@ -1009,10 +1019,13 @@ impl TargetCfgs { // which are respected for `--print=cfg` but not for `--print=all-target-specs-json`. The // code below extracts them from `--print=cfg`: make sure to only override fields that can // actually be changed with `-C` flags. - for config in - rustc_output(config, &["--print=cfg", "--target", &config.target], Default::default()) - .trim() - .lines() + for config in query_rustc_output( + config, + &["--print=cfg", "--target", &config.target], + Default::default(), + ) + .trim() + .lines() { let (name, value) = config .split_once("=\"") @@ -1113,7 +1126,7 @@ pub enum Endian { } fn builtin_cfg_names(config: &Config) -> HashSet { - rustc_output( + query_rustc_output( config, &["--print=check-cfg", "-Zunstable-options", "--check-cfg=cfg()"], Default::default(), @@ -1128,7 +1141,7 @@ pub const KNOWN_CRATE_TYPES: &[&str] = &["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"]; fn supported_crate_types(config: &Config) -> HashSet { - let crate_types: HashSet<_> = rustc_output( + let crate_types: HashSet<_> = query_rustc_output( config, &["--target", &config.target, "--print=supported-crate-types", "-Zunstable-options"], Default::default(), @@ -1149,8 +1162,10 @@ fn supported_crate_types(config: &Config) -> HashSet { crate_types } -fn rustc_output(config: &Config, args: &[&str], envs: HashMap) -> String { - let mut command = Command::new(&config.rustc_path); +fn query_rustc_output(config: &Config, args: &[&str], envs: HashMap) -> String { + let query_rustc_path = config.query_rustc_path.as_deref().unwrap_or(&config.rustc_path); + + let mut command = Command::new(query_rustc_path); add_dylib_path(&mut command, iter::once(&config.compile_lib_path)); command.args(&config.target_rustcflags).args(args); command.env("RUSTC_BOOTSTRAP", "1"); diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index c712185733c68..f5409e783418b 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -63,6 +63,12 @@ pub fn parse_config(args: Vec) -> Config { "path to rustc to use for compiling run-make recipes", "PATH", ) + .optopt( + "", + "query-rustc-path", + "path to rustc to use for querying target information (defaults to `--rustc-path`)", + "PATH", + ) .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH") .optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH") .reqopt("", "python", "path to python to use for doc tests", "PATH") @@ -354,6 +360,7 @@ pub fn parse_config(args: Vec) -> Config { rustc_path: opt_path(matches, "rustc-path"), cargo_path: matches.opt_str("cargo-path").map(Utf8PathBuf::from), stage0_rustc_path: matches.opt_str("stage0-rustc-path").map(Utf8PathBuf::from), + query_rustc_path: matches.opt_str("query-rustc-path").map(Utf8PathBuf::from), rustdoc_path: matches.opt_str("rustdoc-path").map(Utf8PathBuf::from), coverage_dump_path: matches.opt_str("coverage-dump-path").map(Utf8PathBuf::from), python: matches.opt_str("python").unwrap(),