Skip to content

redesign stage 0 std follow-ups #141914

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 5 commits into from
Jun 3, 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
3 changes: 2 additions & 1 deletion src/bootstrap/defaults/bootstrap.library.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# These defaults are meant for contributors to the standard library and documentation.
[build]
bench-stage = 1
build-stage = 1
check-stage = 1
test-stage = 1
bench-stage = 1

[rust]
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
Expand Down
56 changes: 43 additions & 13 deletions src/bootstrap/src/core/build_steps/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub struct Std {
}

impl Std {
const CRATE_OR_DEPS: &[&str] = &["sysroot", "coretests", "alloctests"];

pub fn new(target: TargetSelection) -> Self {
Self { target, crates: vec![], override_build_kind: None }
}
Expand All @@ -46,12 +48,19 @@ impl Step for Std {
const DEFAULT: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let stage = run.builder.top_stage;
run.crate_or_deps("sysroot")
.crate_or_deps("coretests")
.crate_or_deps("alloctests")
.path("library")
.default_condition(stage != 0)
let builder = run.builder;
let stage = if builder.config.is_explicit_stage() || builder.top_stage >= 1 {
builder.top_stage
} else {
1
};

let mut run = run;
for c in Std::CRATE_OR_DEPS {
run = run.crate_or_deps(c);
}

run.path("library").default_condition(stage != 0)
}

fn make_run(run: RunConfig<'_>) {
Expand All @@ -62,10 +71,29 @@ impl Step for Std {
fn run(self, builder: &Builder<'_>) {
builder.require_submodule("library/stdarch", None);

let stage = if builder.config.is_explicit_stage() || builder.top_stage >= 1 {
builder.top_stage
} else {
1
};

let target = self.target;
let compiler = builder.compiler(builder.top_stage, builder.config.build);
let compiler = builder.compiler(stage, builder.config.build);

if stage == 0 {
let mut is_explicitly_called =
builder.paths.iter().any(|p| p.starts_with("library") || p.starts_with("std"));

if !is_explicitly_called {
for c in Std::CRATE_OR_DEPS {
is_explicitly_called = builder.paths.iter().any(|p| p.starts_with(c));
}
}

if is_explicitly_called {
eprintln!("WARNING: stage 0 std is precompiled and does nothing during `x check`.");
}
Comment on lines +93 to +95
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we give this warning unconditionally, or keep it as it is?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would only keep it when the library was explicitly requested, so this seems fine.


if builder.top_stage == 0 {
// Reuse the stage0 libstd
builder.ensure(compile::Std::new(compiler, target));
return;
Expand Down Expand Up @@ -93,6 +121,7 @@ impl Step for Std {
let _guard = builder.msg_check(
format_args!("library artifacts{}", crate_description(&self.crates)),
target,
Some(stage),
);

let stamp = build_stamp::libstd_stamp(builder, compiler, target).with_prefix("check");
Expand Down Expand Up @@ -145,7 +174,7 @@ impl Step for Std {
}

let stamp = build_stamp::libstd_stamp(builder, compiler, target).with_prefix("check-test");
let _guard = builder.msg_check("library test/bench/example targets", target);
let _guard = builder.msg_check("library test/bench/example targets", target, Some(stage));
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
}
}
Expand Down Expand Up @@ -246,6 +275,7 @@ impl Step for Rustc {
let _guard = builder.msg_check(
format_args!("compiler artifacts{}", crate_description(&self.crates)),
target,
None,
);

let stamp = build_stamp::librustc_stamp(builder, compiler, target).with_prefix("check");
Expand Down Expand Up @@ -306,7 +336,7 @@ impl Step for CodegenBackend {
.arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
rustc_cargo_env(builder, &mut cargo, target, compiler.stage);

let _guard = builder.msg_check(backend, target);
let _guard = builder.msg_check(backend, target, None);

let stamp = build_stamp::codegen_backend_stamp(builder, compiler, target, backend)
.with_prefix("check");
Expand Down Expand Up @@ -373,7 +403,7 @@ impl Step for RustAnalyzer {
let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
.with_prefix("rust-analyzer-check");

let _guard = builder.msg_check("rust-analyzer artifacts", target);
let _guard = builder.msg_check("rust-analyzer artifacts", target, None);
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
}
}
Expand Down Expand Up @@ -436,7 +466,7 @@ impl Step for Compiletest {
let stamp = BuildStamp::new(&builder.cargo_out(compiler, mode, self.target))
.with_prefix("compiletest-check");

let _guard = builder.msg_check("compiletest artifacts", self.target);
let _guard = builder.msg_check("compiletest artifacts", self.target, None);
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
}
}
Expand Down Expand Up @@ -514,7 +544,7 @@ fn run_tool_check_step(
let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
.with_prefix(&format!("{}-check", step_type_name.to_lowercase()));

let _guard = builder.msg_check(format!("{display_name} artifacts"), target);
let _guard = builder.msg_check(format!("{display_name} artifacts"), target, None);
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
}

Expand Down
5 changes: 2 additions & 3 deletions src/bootstrap/src/core/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2531,9 +2531,8 @@ impl Config {
|| bench_stage.is_some();
// See https://github.com/rust-lang/compiler-team/issues/326
config.stage = match config.cmd {
Subcommand::Check { .. } | Subcommand::Clippy { .. } | Subcommand::Fix => {
flags.stage.or(check_stage).unwrap_or(1)
}
Subcommand::Check { .. } => flags.stage.or(check_stage).unwrap_or(0),
Subcommand::Clippy { .. } | Subcommand::Fix => flags.stage.or(check_stage).unwrap_or(1),
// `download-rustc` only has a speed-up for stage2 builds. Default to stage2 unless explicitly overridden.
Subcommand::Doc { .. } => {
flags.stage.or(doc_stage).unwrap_or(if download_rustc { 2 } else { 1 })
Expand Down
9 changes: 8 additions & 1 deletion src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1104,8 +1104,15 @@ Executed at: {executed_at}"#,
&self,
what: impl Display,
target: impl Into<Option<TargetSelection>>,
custom_stage: Option<u32>,
) -> Option<gha::Group> {
self.msg(Kind::Check, self.config.stage, what, self.config.build, target)
self.msg(
Kind::Check,
custom_stage.unwrap_or(self.config.stage),
what,
self.config.build,
target,
)
}

#[must_use = "Groups should not be dropped until the Step finishes running"]
Expand Down
1 change: 1 addition & 0 deletions src/ci/docker/host-x86_64/mingw-check-2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

ENV SCRIPT \
python3 ../x.py check && \
python3 ../x.py clippy ci && \
python3 ../x.py test --stage 1 core alloc std test proc_macro && \
# Build both public and internal documentation.
Expand Down
Loading