Skip to content

For "stage 1" ui-fulldeps, use the stage 1 compiler to query target info #144848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 4, 2025
Merged
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
8 changes: 8 additions & 0 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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}"))
};
Expand Down Expand Up @@ -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.
Expand Down
35 changes: 25 additions & 10 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,15 @@ pub struct Config {
/// [`Self::rustc_path`].
pub stage0_rustc_path: Option<Utf8PathBuf>,

/// 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<Utf8PathBuf>,

/// Path to the `rustdoc`-under-test. Like [`Self::rustc_path`], this `rustdoc` is *staged*.
pub rustdoc_path: Option<Utf8PathBuf>,

Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -917,7 +927,7 @@ pub struct TargetCfgs {

impl TargetCfgs {
fn new(config: &Config) -> TargetCfgs {
let mut targets: HashMap<String, TargetCfg> = serde_json::from_str(&rustc_output(
let mut targets: HashMap<String, TargetCfg> = serde_json::from_str(&query_rustc_output(
config,
&["--print=all-target-specs-json", "-Zunstable-options"],
Default::default(),
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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("=\"")
Expand Down Expand Up @@ -1113,7 +1126,7 @@ pub enum Endian {
}

fn builtin_cfg_names(config: &Config) -> HashSet<String> {
rustc_output(
query_rustc_output(
config,
&["--print=check-cfg", "-Zunstable-options", "--check-cfg=cfg()"],
Default::default(),
Expand All @@ -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<String> {
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(),
Expand All @@ -1149,8 +1162,10 @@ fn supported_crate_types(config: &Config) -> HashSet<String> {
crate_types
}

fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
let mut command = Command::new(&config.rustc_path);
fn query_rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> 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");
Expand Down
7 changes: 7 additions & 0 deletions src/tools/compiletest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ pub fn parse_config(args: Vec<String>) -> 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")
Expand Down Expand Up @@ -354,6 +360,7 @@ pub fn parse_config(args: Vec<String>) -> 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(),
Expand Down
Loading