Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 424ee44

Browse files
committedApr 10, 2025·
Auto merge of rust-lang#119899 - onur-ozkan:redesign-stage0-std, r=<try>
redesign stage 0 std ### Summary This PR changes how bootstrap builds the stage 1 compiler by switching to precompiled stage 0 standard library instead of building the in-tree one. The goal was to update bootstrap to use the beta standard library at stage 0 rather than compiling it from source (see the motivation at rust-lang/compiler-team#619). Previously, to build a stage 1 compiler bootstrap followed this path: ``` download stage0 compiler -> build in-tree std -> compile stage1 compiler with in-tree std ``` With this PR, the new path is: ``` download stage0 compiler -> compile stage1 compiler with precompiled stage0 std ``` This also means that `cfg(bootstrap)`/`cfg(not(bootstrap))` is no longer needed for library development. ### Building "library" Since stage0 `std` is no longer in-tree `x build/test/check library --stage 0` is now no-op. The minimum supported stage to build `std` is now 1. For the same reason, default stage values in the library profile is no longer 0. Because building the in-tree library now requires a stage1 compiler, I highly recommend library developers to enable `download-rustc` to speed up compilation time. <hr> If you encounter a bug or unexpected results please open a topic in the [#t-infra/bootstrap](https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap) Zulip channel or create a [bootstrap issue](https://github.com/rust-lang/rust/issues/new?template=bootstrap.md). (Review thread: https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/Review.20thread.3A.20stage.200.20redesign.20PR/with/508271433) ~~Blocked on rust-lang#122709 try-job: dist-x86_64-linux
2 parents 69b3959 + d6f178a commit 424ee44

File tree

30 files changed

+238
-262
lines changed

30 files changed

+238
-262
lines changed
 

‎compiler/rustc_span/src/analyze_source_file.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ cfg_match! {
8484
// For character in the chunk, see if its byte value is < 0, which
8585
// indicates that it's part of a UTF-8 char.
8686
let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0));
87+
8788
// Create a bit mask from the comparison results.
8889
let multibyte_mask = _mm_movemask_epi8(multibyte_test);
8990

@@ -93,6 +94,7 @@ cfg_match! {
9394

9495
// Check for newlines in the chunk
9596
let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8));
97+
9698
let mut newlines_mask = _mm_movemask_epi8(newlines_test);
9799

98100
let output_offset = RelativeBytePos::from_usize(chunk_index * CHUNK_SIZE + 1);

‎library/core/src/fmt/rt.rs‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ pub struct Placeholder {
1616
pub width: Count,
1717
}
1818

19-
#[cfg(bootstrap)]
20-
impl Placeholder {
21-
#[inline]
22-
pub const fn new(position: usize, flags: u32, precision: Count, width: Count) -> Self {
23-
Self { position, flags, precision, width }
24-
}
25-
}
26-
2719
/// Used by [width](https://doc.rust-lang.org/std/fmt/#width)
2820
/// and [precision](https://doc.rust-lang.org/std/fmt/#precision) specifiers.
2921
#[lang = "format_count"]

‎src/bootstrap/defaults/bootstrap.library.toml‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
# These defaults are meant for contributors to the standard library and documentation.
22
[build]
3-
# When building the standard library, you almost never want to build the compiler itself.
4-
build-stage = 0
5-
test-stage = 0
6-
bench-stage = 0
3+
build-stage = 1
4+
test-stage = 1
5+
bench-stage = 1
76

87
[rust]
98
# This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
109
incremental = true
1110
# Make the compiler and standard library faster to build, at the expense of a ~20% runtime slowdown.
1211
lto = "off"
13-
# Download rustc by default for library profile if compiler-affecting
14-
# directories are not modified. For CI this is disabled.
12+
# When building the standard library, you almost never want to build the compiler itself.
13+
#
14+
# If compiler-affecting directories are not modified, use precompiled rustc to speed up
15+
# library development by skipping compiler builds.
1516
download-rustc = "if-unchanged"
1617

1718
[llvm]

‎src/bootstrap/src/core/build_steps/check.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
22
3+
use crate::core::build_steps::compile;
34
use crate::core::build_steps::compile::{
45
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
56
};
@@ -45,10 +46,12 @@ impl Step for Std {
4546
const DEFAULT: bool = true;
4647

4748
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
49+
let stage = run.builder.top_stage;
4850
run.crate_or_deps("sysroot")
4951
.crate_or_deps("coretests")
5052
.crate_or_deps("alloctests")
5153
.path("library")
54+
.default_condition(stage != 0)
5255
}
5356

5457
fn make_run(run: RunConfig<'_>) {
@@ -62,6 +65,12 @@ impl Step for Std {
6265
let target = self.target;
6366
let compiler = builder.compiler(builder.top_stage, builder.config.build);
6467

68+
if builder.top_stage == 0 {
69+
// Reuse the stage0 libstd
70+
builder.ensure(compile::Std::new(compiler, target));
71+
return;
72+
}
73+
6574
let mut cargo = builder::Cargo::new(
6675
builder,
6776
compiler,

‎src/bootstrap/src/core/build_steps/clippy.rs‎

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,16 +207,18 @@ impl Step for Rustc {
207207
let compiler = builder.compiler(builder.top_stage, builder.config.build);
208208
let target = self.target;
209209

210-
if compiler.stage != 0 {
211-
// If we're not in stage 0, then we won't have a std from the beta
212-
// compiler around. That means we need to make sure there's one in
213-
// the sysroot for the compiler to find. Otherwise, we're going to
214-
// fail when building crates that need to generate code (e.g., build
215-
// scripts and their dependencies).
216-
builder.ensure(compile::Std::new(compiler, compiler.host));
217-
builder.ensure(compile::Std::new(compiler, target));
218-
} else {
219-
builder.ensure(check::Std::new(target).build_kind(Some(Kind::Check)));
210+
if !builder.download_rustc() {
211+
if compiler.stage != 0 {
212+
// If we're not in stage 0, then we won't have a std from the beta
213+
// compiler around. That means we need to make sure there's one in
214+
// the sysroot for the compiler to find. Otherwise, we're going to
215+
// fail when building crates that need to generate code (e.g., build
216+
// scripts and their dependencies).
217+
builder.ensure(compile::Std::new(compiler, compiler.host));
218+
builder.ensure(compile::Std::new(compiler, target));
219+
} else {
220+
builder.ensure(check::Std::new(target).build_kind(Some(Kind::Check)));
221+
}
220222
}
221223

222224
let mut cargo = builder::Cargo::new(
@@ -286,7 +288,9 @@ macro_rules! lint_any {
286288
let compiler = builder.compiler(builder.top_stage, builder.config.build);
287289
let target = self.target;
288290

289-
builder.ensure(check::Rustc::new(target, builder).build_kind(Some(Kind::Check)));
291+
if !builder.download_rustc() {
292+
builder.ensure(check::Rustc::new(target, builder).build_kind(Some(Kind::Check)));
293+
};
290294

291295
let cargo = prepare_tool_cargo(
292296
builder,

‎src/bootstrap/src/core/build_steps/compile.rs‎

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,26 @@ impl Step for Std {
151151
)]
152152
fn run(self, builder: &Builder<'_>) {
153153
let target = self.target;
154-
let compiler = self.compiler;
154+
155+
// We already have std ready to be used for stage 0.
156+
if self.compiler.stage == 0 {
157+
let compiler = self.compiler;
158+
builder.ensure(StdLink::from_std(self, compiler));
159+
160+
return;
161+
}
162+
163+
let compiler = if builder.download_rustc() && self.force_recompile {
164+
// When there are changes in the library tree with CI-rustc, we want to build
165+
// the stageN library and that requires using stageN-1 compiler.
166+
builder.compiler(self.compiler.stage.saturating_sub(1), builder.config.build)
167+
} else {
168+
self.compiler
169+
};
155170

156171
// When using `download-rustc`, we already have artifacts for the host available. Don't
157172
// recompile them.
158-
if builder.download_rustc() && builder.is_builder_target(target)
159-
// NOTE: the beta compiler may generate different artifacts than the downloaded compiler, so
160-
// its artifacts can't be reused.
161-
&& compiler.stage != 0
162-
&& !self.force_recompile
163-
{
173+
if builder.download_rustc() && builder.is_builder_target(target) && !self.force_recompile {
164174
let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false });
165175
cp_rustc_component_to_ci_sysroot(
166176
builder,
@@ -193,7 +203,13 @@ impl Step for Std {
193203
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
194204
trace!(?compiler_to_use);
195205

196-
if compiler_to_use != compiler {
206+
if compiler_to_use != compiler
207+
// Never uplift std unless we have compiled stage 1; if stage 1 is compiled,
208+
// uplift it from there.
209+
//
210+
// FIXME: improve `fn compiler_for` to avoid adding stage condition here.
211+
&& compiler.stage > 1
212+
{
197213
trace!(?compiler_to_use, ?compiler, "compiler != compiler_to_use, uplifting library");
198214

199215
builder.ensure(Std::new(compiler_to_use, target));
@@ -226,27 +242,6 @@ impl Step for Std {
226242

227243
target_deps.extend(self.copy_extra_objects(builder, &compiler, target));
228244

229-
// The LLD wrappers and `rust-lld` are self-contained linking components that can be
230-
// necessary to link the stdlib on some targets. We'll also need to copy these binaries to
231-
// the `stage0-sysroot` to ensure the linker is found when bootstrapping on such a target.
232-
if compiler.stage == 0 && builder.is_builder_target(compiler.host) {
233-
trace!(
234-
"(build == host) copying linking components to `stage0-sysroot` for bootstrapping"
235-
);
236-
// We want to copy the host `bin` folder within the `rustlib` folder in the sysroot.
237-
let src_sysroot_bin = builder
238-
.rustc_snapshot_sysroot()
239-
.join("lib")
240-
.join("rustlib")
241-
.join(compiler.host)
242-
.join("bin");
243-
if src_sysroot_bin.exists() {
244-
let target_sysroot_bin = builder.sysroot_target_bindir(compiler, target);
245-
t!(fs::create_dir_all(&target_sysroot_bin));
246-
builder.cp_link_r(&src_sysroot_bin, &target_sysroot_bin);
247-
}
248-
}
249-
250245
// We build a sysroot for mir-opt tests using the same trick that Miri does: A check build
251246
// with -Zalways-encode-mir. This frees us from the need to have a target linker, and the
252247
// fact that this is a check build integrates nicely with run_cargo.
@@ -741,7 +736,7 @@ impl Step for StdLink {
741736
let target = self.target;
742737

743738
// NOTE: intentionally does *not* check `target == builder.build` to avoid having to add the same check in `test::Crate`.
744-
let (libdir, hostdir) = if self.force_recompile && builder.download_rustc() {
739+
let (libdir, hostdir) = if !self.force_recompile && builder.download_rustc() {
745740
// NOTE: copies part of `sysroot_libdir` to avoid having to add a new `force_recompile` argument there too
746741
let lib = builder.sysroot_libdir_relative(self.compiler);
747742
let sysroot = builder.ensure(crate::core::build_steps::compile::Sysroot {
@@ -757,23 +752,16 @@ impl Step for StdLink {
757752
(libdir, hostdir)
758753
};
759754

760-
add_to_sysroot(
761-
builder,
762-
&libdir,
763-
&hostdir,
764-
&build_stamp::libstd_stamp(builder, compiler, target),
765-
);
755+
let is_downloaded_beta_stage0 = builder
756+
.build
757+
.config
758+
.initial_rustc
759+
.starts_with(builder.out.join(compiler.host).join("stage0/bin"));
766760

767761
// Special case for stage0, to make `rustup toolchain link` and `x dist --stage 0`
768762
// work for stage0-sysroot. We only do this if the stage0 compiler comes from beta,
769763
// and is not set to a custom path.
770-
if compiler.stage == 0
771-
&& builder
772-
.build
773-
.config
774-
.initial_rustc
775-
.starts_with(builder.out.join(compiler.host).join("stage0/bin"))
776-
{
764+
if compiler.stage == 0 && is_downloaded_beta_stage0 {
777765
// Copy bin files from stage0/bin to stage0-sysroot/bin
778766
let sysroot = builder.out.join(compiler.host).join("stage0-sysroot");
779767

@@ -783,21 +771,9 @@ impl Step for StdLink {
783771
t!(fs::create_dir_all(&sysroot_bin_dir));
784772
builder.cp_link_r(&stage0_bin_dir, &sysroot_bin_dir);
785773

786-
// Copy all files from stage0/lib to stage0-sysroot/lib
787774
let stage0_lib_dir = builder.out.join(host).join("stage0/lib");
788-
if let Ok(files) = fs::read_dir(stage0_lib_dir) {
789-
for file in files {
790-
let file = t!(file);
791-
let path = file.path();
792-
if path.is_file() {
793-
builder.copy_link(
794-
&path,
795-
&sysroot.join("lib").join(path.file_name().unwrap()),
796-
FileType::Regular,
797-
);
798-
}
799-
}
800-
}
775+
t!(fs::create_dir_all(sysroot.join("lib")));
776+
builder.cp_link_r(&stage0_lib_dir, &sysroot.join("lib"));
801777

802778
// Copy codegen-backends from stage0
803779
let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler);
@@ -811,6 +787,30 @@ impl Step for StdLink {
811787
if stage0_codegen_backends.exists() {
812788
builder.cp_link_r(&stage0_codegen_backends, &sysroot_codegen_backends);
813789
}
790+
} else if compiler.stage == 0 {
791+
let sysroot = builder.out.join(compiler.host.triple).join("stage0-sysroot");
792+
793+
if builder.local_rebuild {
794+
// On local rebuilds this path might be a symlink to the project root,
795+
// which can be read-only (e.g., on CI). So remove it before copying
796+
// the stage0 lib.
797+
let _ = fs::remove_dir_all(sysroot.join("lib/rustlib/src/rust"));
798+
}
799+
800+
builder.cp_link_r(&builder.initial_sysroot.join("lib"), &sysroot.join("lib"));
801+
} else {
802+
if builder.download_rustc() {
803+
// Ensure there are no CI-rustc std artifacts.
804+
let _ = fs::remove_dir_all(&libdir);
805+
let _ = fs::remove_dir_all(&hostdir);
806+
}
807+
808+
add_to_sysroot(
809+
builder,
810+
&libdir,
811+
&hostdir,
812+
&build_stamp::libstd_stamp(builder, compiler, target),
813+
);
814814
}
815815
}
816816
}
@@ -1033,7 +1033,7 @@ impl Step for Rustc {
10331033
let compiler = self.compiler;
10341034
let target = self.target;
10351035

1036-
// NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler,
1036+
// NOTE: the ABI of the stage0 compiler is different from the ABI of the downloaded compiler,
10371037
// so its artifacts can't be reused.
10381038
if builder.download_rustc() && compiler.stage != 0 {
10391039
trace!(stage = compiler.stage, "`download_rustc` requested");
@@ -1788,9 +1788,9 @@ impl Step for Sysroot {
17881788
t!(fs::create_dir_all(&sysroot));
17891789

17901790
// In some cases(see https://github.com/rust-lang/rust/issues/109314), when the stage0
1791-
// compiler relies on more recent version of LLVM than the beta compiler, it may not
1791+
// compiler relies on more recent version of LLVM than the stage0 compiler, it may not
17921792
// be able to locate the correct LLVM in the sysroot. This situation typically occurs
1793-
// when we upgrade LLVM version while the beta compiler continues to use an older version.
1793+
// when we upgrade LLVM version while the stage0 compiler continues to use an older version.
17941794
//
17951795
// Make sure to add the correct version of LLVM into the stage0 sysroot.
17961796
if compiler.stage == 0 {

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ impl Step for Compiletest {
15581558

15591559
if builder.top_stage == 0 && env::var("COMPILETEST_FORCE_STAGE0").is_err() {
15601560
eprintln!("\
1561-
ERROR: `--stage 0` runs compiletest on the beta compiler, not your local changes, and will almost always cause tests to fail
1561+
ERROR: `--stage 0` runs compiletest on the stage0 (precompiled) compiler, not your local changes, and will almost always cause tests to fail
15621562
HELP: to test the compiler, use `--stage 1` instead
15631563
HELP: to test the standard library, use `--stage 0 library/std` instead
15641564
NOTE: if you're sure you want to do this, please open an issue as to why. In the meantime, you can override this with `COMPILETEST_FORCE_STAGE0=1`."
@@ -1586,9 +1586,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
15861586
// NOTE: Only stage 1 is special cased because we need the rustc_private artifacts to match the
15871587
// running compiler in stage 2 when plugins run.
15881588
let (stage, stage_id) = if suite == "ui-fulldeps" && compiler.stage == 1 {
1589-
// At stage 0 (stage - 1) we are using the beta compiler. Using `self.target` can lead
1590-
// finding an incorrect compiler path on cross-targets, as the stage 0 beta compiler is
1591-
// always equal to `build.build` in the configuration.
1589+
// At stage 0 (stage - 1) we are using the stage0 compiler. Using `self.target` can lead
1590+
// finding an incorrect compiler path on cross-targets, as the stage 0 is always equal to
1591+
// `build.build` in the configuration.
15921592
let build = builder.build.build;
15931593
compiler = builder.compiler(compiler.stage - 1, build);
15941594
let test_stage = compiler.stage + 1;
@@ -1674,7 +1674,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
16741674
}
16751675

16761676
if mode == "rustdoc-json" {
1677-
// Use the beta compiler for jsondocck
1677+
// Use the stage0 compiler for jsondocck
16781678
let json_compiler = compiler.with_stage(0);
16791679
cmd.arg("--jsondocck-path")
16801680
.arg(builder.ensure(tool::JsonDocCk { compiler: json_compiler, target }).tool_path);

‎src/bootstrap/src/core/build_steps/tool.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,9 @@ pub(crate) fn get_tool_rustc_compiler(
330330
return target_compiler;
331331
}
332332

333-
if builder.download_rustc() && target_compiler.stage > 0 {
334-
// We already have the stage N compiler, we don't need to cut the stage.
335-
return builder.compiler(target_compiler.stage, builder.config.build);
333+
if builder.download_rustc() && target_compiler.stage == 1 {
334+
// We shouldn't drop to stage0 compiler when using CI rustc.
335+
return builder.compiler(1, builder.config.build);
336336
}
337337

338338
// Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise

‎src/bootstrap/src/core/builder/tests.rs‎

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ fn alias_and_path_for_library() {
234234
);
235235
assert_eq!(
236236
first(cache.all::<doc::Std>()),
237-
&[doc_std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0)]
237+
&[doc_std!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1)]
238238
);
239239
}
240240

@@ -259,16 +259,10 @@ fn ci_rustc_if_unchanged_logic() {
259259
builder.run_step_descriptions(&Builder::get_step_descriptions(config.cmd.kind()), &[]);
260260

261261
// Make sure "if-unchanged" logic doesn't try to use CI rustc while there are changes
262-
// in compiler and/or library.
262+
// in "compiler" tree.
263263
if config.download_rustc_commit.is_some() {
264-
let mut paths = vec!["compiler"];
265-
266-
// Handle library tree the same way as in `Config::download_ci_rustc_commit`.
267-
if builder.config.is_running_on_ci {
268-
paths.push("library");
269-
}
270-
271-
let has_changes = config.last_modified_commit(&paths, "download-rustc", true).is_none();
264+
let has_changes =
265+
config.last_modified_commit(&["compiler"], "download-rustc", true).is_none();
272266

273267
assert!(
274268
!has_changes,
@@ -392,14 +386,14 @@ mod defaults {
392386
assert_eq!(first(cache.all::<doc::ErrorIndex>()), &[doc::ErrorIndex { target: a },]);
393387
assert_eq!(
394388
first(cache.all::<tool::ErrorIndex>()),
395-
&[tool::ErrorIndex { compiler: Compiler::new(0, a) }]
389+
&[tool::ErrorIndex { compiler: Compiler::new(1, a) }]
396390
);
397-
// docs should be built with the beta compiler, not with the stage0 artifacts.
391+
// docs should be built with the stage0 compiler, not with the stage0 artifacts.
398392
// recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to,
399393
// not the one it was built by.
400394
assert_eq!(
401395
first(cache.all::<tool::Rustdoc>()),
402-
&[tool::Rustdoc { compiler: Compiler::new(0, a) },]
396+
&[tool::Rustdoc { compiler: Compiler::new(1, a) },]
403397
);
404398
}
405399
}

‎src/bootstrap/src/core/config/config.rs‎

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use crate::utils::helpers::{self, exe, output, t};
4444
/// final output/compiler, which can be significantly affected by changes made to the bootstrap sources.
4545
#[rustfmt::skip] // We don't want rustfmt to oneline this list
4646
pub(crate) const RUSTC_IF_UNCHANGED_ALLOWED_PATHS: &[&str] = &[
47+
":!library",
4748
":!src/tools",
4849
":!src/librustdoc",
4950
":!src/rustdoc-json-types",
@@ -2433,10 +2434,12 @@ impl Config {
24332434
|| bench_stage.is_some();
24342435
// See https://github.com/rust-lang/compiler-team/issues/326
24352436
config.stage = match config.cmd {
2436-
Subcommand::Check { .. } => flags.stage.or(check_stage).unwrap_or(0),
2437+
Subcommand::Check { .. } | Subcommand::Clippy { .. } | Subcommand::Fix => {
2438+
flags.stage.or(check_stage).unwrap_or(1)
2439+
}
24372440
// `download-rustc` only has a speed-up for stage2 builds. Default to stage2 unless explicitly overridden.
24382441
Subcommand::Doc { .. } => {
2439-
flags.stage.or(doc_stage).unwrap_or(if download_rustc { 2 } else { 0 })
2442+
flags.stage.or(doc_stage).unwrap_or(if download_rustc { 2 } else { 1 })
24402443
}
24412444
Subcommand::Build => {
24422445
flags.stage.or(build_stage).unwrap_or(if download_rustc { 2 } else { 1 })
@@ -2451,8 +2454,6 @@ impl Config {
24512454
// These are all bootstrap tools, which don't depend on the compiler.
24522455
// The stage we pass shouldn't matter, but use 0 just in case.
24532456
Subcommand::Clean { .. }
2454-
| Subcommand::Clippy { .. }
2455-
| Subcommand::Fix
24562457
| Subcommand::Run { .. }
24572458
| Subcommand::Setup { .. }
24582459
| Subcommand::Format { .. }
@@ -3063,24 +3064,14 @@ impl Config {
30633064
}
30643065
};
30653066

3066-
// RUSTC_IF_UNCHANGED_ALLOWED_PATHS
3067-
let mut allowed_paths = RUSTC_IF_UNCHANGED_ALLOWED_PATHS.to_vec();
3068-
3069-
// In CI, disable ci-rustc if there are changes in the library tree. But for non-CI, allow
3070-
// these changes to speed up the build process for library developers. This provides consistent
3071-
// functionality for library developers between `download-rustc=true` and `download-rustc="if-unchanged"`
3072-
// options.
3073-
//
3074-
// If you update "library" logic here, update `builder::tests::ci_rustc_if_unchanged_logic` test
3075-
// logic accordingly.
3076-
if !self.is_running_on_ci {
3077-
allowed_paths.push(":!library");
3078-
}
3079-
30803067
let commit = if self.rust_info.is_managed_git_subrepository() {
30813068
// Look for a version to compare to based on the current commit.
30823069
// Only commits merged by bors will have CI artifacts.
3083-
match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged) {
3070+
match self.last_modified_commit(
3071+
RUSTC_IF_UNCHANGED_ALLOWED_PATHS,
3072+
"download-rustc",
3073+
if_unchanged,
3074+
) {
30843075
Some(commit) => commit,
30853076
None => {
30863077
if if_unchanged {

‎src/bootstrap/src/core/download.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ impl Config {
662662
}
663663
};
664664

665-
// For the beta compiler, put special effort into ensuring the checksums are valid.
665+
// For the stage0 compiler, put special effort into ensuring the checksums are valid.
666666
let checksum = if should_verify {
667667
let error = format!(
668668
"src/stage0 doesn't contain a checksum for {url}. \

‎src/bootstrap/src/utils/change_tracker.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,4 +396,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
396396
severity: ChangeSeverity::Info,
397397
summary: "Added a new option `build.compiletest-use-stage0-libtest` to force `compiletest` to use the stage 0 libtest.",
398398
},
399+
ChangeInfo {
400+
change_id: 119899,
401+
severity: ChangeSeverity::Warning,
402+
summary: "Stage0 library no longer matches the in-tree library, which means stage1 compiler now uses the beta library.",
403+
},
399404
];

‎src/ci/citool/src/jobs.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::GitHubContext;
1010
/// Representation of a job loaded from the `src/ci/github-actions/jobs.yml` file.
1111
#[derive(serde::Deserialize, Debug, Clone)]
1212
pub struct Job {
13-
/// Name of the job, e.g. mingw-check
13+
/// Name of the job, e.g. mingw-check-1
1414
pub name: String,
1515
/// GitHub runner on which the job should be executed
1616
pub os: String,

‎src/ci/citool/tests/jobs.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ try-job: dist-i686-msvc"#,
4040
fn pr_jobs() {
4141
let stdout = get_matrix("pull_request", "commit", "refs/heads/pr/1234");
4242
insta::assert_snapshot!(stdout, @r#"
43-
jobs=[{"name":"mingw-check","full_name":"PR - mingw-check","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"mingw-check-tidy","full_name":"PR - mingw-check-tidy","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"continue_on_error":true,"free_disk":true,"doc_url":"https://foo.bar"}]
43+
jobs=[{"name":"mingw-check-1","full_name":"PR - mingw-check-1","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"mingw-check-2","full_name":"PR - mingw-check-2","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"mingw-check-tidy","full_name":"PR - mingw-check-tidy","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"continue_on_error":true,"free_disk":true,"doc_url":"https://foo.bar"}]
4444
run_type=pr
4545
"#);
4646
}

‎src/ci/citool/tests/test-jobs.yml‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ envs:
6464
# These jobs automatically inherit envs.pr, to avoid repeating
6565
# it in each job definition.
6666
pr:
67-
- name: mingw-check
67+
- name: mingw-check-1
68+
<<: *job-linux-4c
69+
- name: mingw-check-2
6870
<<: *job-linux-4c
6971
- name: mingw-check-tidy
7072
continue_on_error: true

‎src/ci/docker/host-x86_64/mingw-check/Dockerfile‎ renamed to ‎src/ci/docker/host-x86_64/mingw-check-1/Dockerfile‎

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,31 +34,23 @@ RUN npm install es-check@6.1.1 eslint@8.6.0 typescript@5.7.3 -g
3434
COPY scripts/sccache.sh /scripts/
3535
RUN sh /scripts/sccache.sh
3636

37-
COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
37+
COPY host-x86_64/mingw-check-1/reuse-requirements.txt /tmp/
3838
RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt
3939

40-
COPY host-x86_64/mingw-check/check-default-config-profiles.sh /scripts/
41-
COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
42-
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
40+
COPY host-x86_64/mingw-check-1/check-default-config-profiles.sh /scripts/
41+
COPY host-x86_64/mingw-check-1/validate-toolstate.sh /scripts/
42+
COPY host-x86_64/mingw-check-1/validate-error-codes.sh /scripts/
4343

4444
# Check library crates on all tier 1 targets.
4545
# We disable optimized compiler built-ins because that requires a C toolchain for the target.
4646
# We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs.
4747
ENV SCRIPT \
48-
python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
4948
/scripts/check-default-config-profiles.sh && \
50-
python3 ../x.py check compiletest --set build.compiletest-use-stage0-libtest=true && \
51-
python3 ../x.py check --target=x86_64-pc-windows-gnu --host=x86_64-pc-windows-gnu && \
52-
python3 ../x.py clippy ci && \
5349
python3 ../x.py build --stage 0 src/tools/build-manifest && \
5450
python3 ../x.py test --stage 0 src/tools/compiletest && \
55-
python3 ../x.py test --stage 0 core alloc std test proc_macro && \
56-
# Build both public and internal documentation.
57-
RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 0 library && \
58-
mkdir -p /checkout/obj/staging/doc && \
59-
cp -r build/x86_64-unknown-linux-gnu/doc /checkout/obj/staging && \
60-
RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 0 compiler && \
61-
RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 0 library/test && \
51+
python3 ../x.py check compiletest --set build.compiletest-use-stage0-libtest=true && \
52+
python3 ../x.py check --stage 1 --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
53+
python3 ../x.py check --stage 1 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
6254
/scripts/validate-toolstate.sh && \
6355
/scripts/validate-error-codes.sh && \
6456
reuse --include-submodules lint && \
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
FROM ubuntu:22.04
2+
3+
ARG DEBIAN_FRONTEND=noninteractive
4+
RUN apt-get update && apt-get install -y --no-install-recommends \
5+
g++ \
6+
make \
7+
ninja-build \
8+
file \
9+
curl \
10+
ca-certificates \
11+
python3 \
12+
python3-pip \
13+
python3-pkg-resources \
14+
git \
15+
cmake \
16+
sudo \
17+
gdb \
18+
xz-utils \
19+
libssl-dev \
20+
pkg-config \
21+
mingw-w64 \
22+
&& rm -rf /var/lib/apt/lists/*
23+
24+
ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3"
25+
26+
COPY scripts/sccache.sh /scripts/
27+
RUN sh /scripts/sccache.sh
28+
29+
ENV SCRIPT \
30+
python3 ../x.py clippy ci && \
31+
python3 ../x.py test --stage 1 core alloc std test proc_macro && \
32+
# Build both public and internal documentation.
33+
RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 0 compiler && \
34+
RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 1 library && \
35+
mkdir -p /checkout/obj/staging/doc && \
36+
cp -r build/x86_64-unknown-linux-gnu/doc /checkout/obj/staging && \
37+
RUSTDOCFLAGS=\"--document-private-items --document-hidden-items\" python3 ../x.py doc --stage 1 library/test

‎src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
2727
COPY scripts/sccache.sh /scripts/
2828
RUN sh /scripts/sccache.sh
2929

30-
COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
30+
COPY host-x86_64/mingw-check-1/reuse-requirements.txt /tmp/
3131
RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt \
3232
&& pip3 install virtualenv
3333

34-
COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
35-
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
34+
COPY host-x86_64/mingw-check-1/validate-toolstate.sh /scripts/
35+
COPY host-x86_64/mingw-check-1/validate-error-codes.sh /scripts/
3636

3737
# NOTE: intentionally uses python2 for x.py so we can test it still works.
3838
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.

‎src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ RUN echo "optimize = false" >> /config/nopt-std-config.toml
2929
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu \
3030
--disable-optimize-tests \
3131
--set rust.test-compare-mode
32-
ENV SCRIPT python3 ../x.py test --stage 0 --config /config/nopt-std-config.toml library/std \
32+
ENV SCRIPT python3 ../x.py test --stage 1 --config /config/nopt-std-config.toml library/std \
3333
&& python3 ../x.py --stage 2 test

‎src/ci/github-actions/jobs.yml‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ envs:
100100
# These jobs automatically inherit envs.pr, to avoid repeating
101101
# it in each job definition.
102102
pr:
103-
- name: mingw-check
103+
- name: mingw-check-1
104+
<<: *job-linux-4c
105+
- name: mingw-check-2
104106
<<: *job-linux-4c
105107
- name: mingw-check-tidy
106108
continue_on_error: true
@@ -250,11 +252,14 @@ auto:
250252
env:
251253
IMAGE: i686-gnu-nopt
252254
DOCKER_SCRIPT: >-
253-
python3 ../x.py test --stage 0 --config /config/nopt-std-config.toml library/std &&
255+
python3 ../x.py test --stage 1 --config /config/nopt-std-config.toml library/std &&
254256
/scripts/stage_2_test_set2.sh
255257
<<: *job-linux-4c
256258

257-
- name: mingw-check
259+
- name: mingw-check-1
260+
<<: *job-linux-4c
261+
262+
- name: mingw-check-2
258263
<<: *job-linux-4c
259264

260265
- name: test-various

‎src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md‎

Lines changed: 35 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ compiler.
4545

4646
```mermaid
4747
graph TD
48-
s0c["stage0 compiler (1.63)"]:::downloaded -->|A| s0l("stage0 std (1.64)"):::with-s0c;
48+
s0c["stage0 compiler (1.86.0-beta.1)"]:::downloaded -->|A| s0l("stage0 std (1.86.0-beta.1)"):::downloaded;
4949
s0c & s0l --- stepb[ ]:::empty;
50-
stepb -->|B| s0ca["stage0 compiler artifacts (1.64)"]:::with-s0c;
51-
s0ca -->|copy| s1c["stage1 compiler (1.64)"]:::with-s0c;
52-
s1c -->|C| s1l("stage1 std (1.64)"):::with-s1c;
50+
stepb -->|B| s0ca["stage0 compiler artifacts (1.87.0-dev)"]:::with-s0c;
51+
s0ca -->|copy| s1c["stage1 compiler (1.87.0-dev)"]:::with-s0c;
52+
s1c -->|C| s1l("stage1 std (1.87.0-dev)"):::with-s1c;
5353
s1c & s1l --- stepd[ ]:::empty;
54-
stepd -->|D| s1ca["stage1 compiler artifacts (1.64)"]:::with-s1c;
54+
stepd -->|D| s1ca["stage1 compiler artifacts (1.87.0-dev)"]:::with-s1c;
5555
s1ca -->|copy| s2c["stage2 compiler"]:::with-s1c;
5656
5757
classDef empty width:0px,height:0px;
@@ -62,19 +62,21 @@ graph TD
6262

6363
### Stage 0: the pre-compiled compiler
6464

65-
The stage0 compiler is usually the current _beta_ `rustc` compiler and its
65+
The stage0 compiler is by default the very recent _beta_ `rustc` compiler and its
6666
associated dynamic libraries, which `./x.py` will download for you. (You can
67-
also configure `./x.py` to use something else.)
67+
also configure `./x.py` to change stage0 to something else.)
6868

69-
The stage0 compiler is then used only to compile [`src/bootstrap`],
70-
[`library/std`], and [`compiler/rustc`]. When assembling the libraries and
71-
binaries that will become the stage1 `rustc` compiler, the freshly compiled
72-
`std` and `rustc` are used. There are two concepts at play here: a compiler
73-
(with its set of dependencies) and its 'target' or 'object' libraries (`std` and
74-
`rustc`). Both are staged, but in a staggered manner.
69+
The precompiled stage0 compiler is then used only to compile [`src/bootstrap`] and [`compiler/rustc`]
70+
with precompiled stage0 std.
71+
72+
Note that to build the stage1 compiler we use the precompiled stage0 compiler and std.
73+
Therefore, to use a compiler with a std that is freshly built from the tree, you need to
74+
build the stage2 compiler.
75+
76+
There are two concepts at play here: a compiler (with its set of dependencies) and its
77+
'target' or 'object' libraries (`std` and `rustc`). Both are staged, but in a staggered manner.
7578

7679
[`compiler/rustc`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc
77-
[`library/std`]: https://github.com/rust-lang/rust/tree/master/library/std
7880
[`src/bootstrap`]: https://github.com/rust-lang/rust/tree/master/src/bootstrap
7981

8082
### Stage 1: from current code, by an earlier compiler
@@ -84,26 +86,25 @@ The rustc source code is then compiled with the `stage0` compiler to produce the
8486

8587
### Stage 2: the truly current compiler
8688

87-
We then rebuild our `stage1` compiler with itself to produce the `stage2`
89+
We then rebuild the compiler using `stage1` compiler with in-tree std to produce the `stage2`
8890
compiler.
8991

90-
In theory, the `stage1` compiler is functionally identical to the `stage2`
91-
compiler, but in practice there are subtle differences. In particular, the
92-
`stage1` compiler itself was built by `stage0` and hence not by the source in
93-
your working directory. This means that the ABI generated by the `stage0`
94-
compiler may not match the ABI that would have been made by the `stage1`
95-
compiler, which can cause problems for dynamic libraries, tests, and tools using
96-
`rustc_private`.
92+
The `stage1` compiler itself was built by precompiled `stage0` compiler and std
93+
and hence not by the source in your working directory. This means that the ABI
94+
generated by the `stage0` compiler may not match the ABI that would have been made
95+
by the `stage1` compiler, which can cause problems for dynamic libraries, tests
96+
and tools using `rustc_private`.
9797

9898
Note that the `proc_macro` crate avoids this issue with a `C` FFI layer called
9999
`proc_macro::bridge`, allowing it to be used with `stage1`.
100100

101101
The `stage2` compiler is the one distributed with `rustup` and all other install
102102
methods. However, it takes a very long time to build because one must first
103103
build the new compiler with an older compiler and then use that to build the new
104-
compiler with itself. For development, you usually only want the `stage1`
105-
compiler, which you can build with `./x build library`. See [Building the
106-
compiler](../how-to-build-and-run.html#building-the-compiler).
104+
compiler with itself.
105+
106+
For development, you usually only want to use `--stage 1` flag to build things.
107+
See [Building the compiler](../how-to-build-and-run.html#building-the-compiler).
107108

108109
### Stage 3: the same-result test
109110

@@ -114,10 +115,11 @@ something has broken.
114115
### Building the stages
115116

116117
The script [`./x`] tries to be helpful and pick the stage you most likely meant
117-
for each subcommand. These defaults are as follows:
118+
for each subcommand. Here are some `x` commands with their default stages:
118119

119-
- `check`: `--stage 0`
120-
- `doc`: `--stage 0`
120+
- `check`: `--stage 1`
121+
- `clippy`: `--stage 1`
122+
- `doc`: `--stage 1`
121123
- `build`: `--stage 1`
122124
- `test`: `--stage 1`
123125
- `dist`: `--stage 2`
@@ -191,8 +193,8 @@ include, but are not limited to:
191193
without building `rustc` from source ('build with `stage0`, then test the
192194
artifacts'). If you're working on the standard library, this is normally the
193195
test command you want.
194-
- `./x build --stage 0` means to build with the beta `rustc`.
195-
- `./x doc --stage 0` means to document using the beta `rustdoc`.
196+
- `./x build --stage 0` means to build with the stage0 `rustc`.
197+
- `./x doc --stage 0` means to document using the stage0 `rustdoc`.
196198

197199
#### Examples of what *not* to do
198200

@@ -208,9 +210,6 @@ include, but are not limited to:
208210

209211
### Building vs. running
210212

211-
Note that `build --stage N compiler/rustc` **does not** build the stage N
212-
compiler: instead it builds the stage N+1 compiler _using_ the stage N compiler.
213-
214213
In short, _stage 0 uses the `stage0` compiler to create `stage0` artifacts which
215214
will later be uplifted to be the stage1 compiler_.
216215

@@ -268,23 +267,6 @@ However, when cross-compiling, `stage1` `std` will only run on the host. So the
268267

269268
(See in the table how `stage2` only builds non-host `std` targets).
270269

271-
### Why does only libstd use `cfg(bootstrap)`?
272-
273-
For docs on `cfg(bootstrap)` itself, see [Complications of
274-
Bootstrapping](#complications-of-bootstrapping).
275-
276-
The `rustc` generated by the `stage0` compiler is linked to the freshly-built
277-
`std`, which means that for the most part only `std` needs to be `cfg`-gated, so
278-
that `rustc` can use features added to `std` immediately after their addition,
279-
without need for them to get into the downloaded `beta` compiler.
280-
281-
Note this is different from any other Rust program: `stage1` `rustc` is built by
282-
the _beta_ compiler, but using the _master_ version of `libstd`!
283-
284-
The only time `rustc` uses `cfg(bootstrap)` is when it adds internal lints that
285-
use diagnostic items, or when it uses unstable library features that were
286-
recently changed.
287-
288270
### What is a 'sysroot'?
289271

290272
When you build a project with `cargo`, the build artifacts for dependencies are
@@ -459,7 +441,6 @@ compiler itself uses to run. These aren't actually used by artifacts the new
459441
compiler generates. This step also copies the `rustc` and `rustdoc` binaries we
460442
generated into `build/$HOST/stage/bin`.
461443

462-
The `stage1/bin/rustc` is a fully functional compiler, but it doesn't yet have
463-
any libraries to link built binaries or libraries to. The next 3 steps will
464-
provide those libraries for it; they are mostly equivalent to constructing the
465-
`stage1/bin` compiler so we don't go through them individually here.
444+
The `stage1/bin/rustc` is a fully functional compiler built with stage0 (precompiled) compiler and std.
445+
To use a compiler built entirely from source with the in-tree compiler and std, you need to build the
446+
stage2 compiler, which is compiled using the stage1 (in-tree) compiler and std.

‎src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md‎

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ probably the best "go to" command for building a local compiler:
217217
This may *look* like it only builds the standard library, but that is not the case.
218218
What this command does is the following:
219219

220-
- Build `std` using the stage0 compiler
221220
- Build `rustc` using the stage0 compiler
222221
- This produces the stage1 compiler
223222
- Build `std` using the stage1 compiler
@@ -241,23 +240,22 @@ build. The **full** `rustc` build (what you get with `./x build
241240
--stage 2 compiler/rustc`) has quite a few more steps:
242241

243242
- Build `rustc` with the stage1 compiler.
244-
- The resulting compiler here is called the "stage2" compiler.
245-
- Build `std` with stage2 compiler.
243+
- The resulting compiler here is called the "stage2" compiler, which uses stage1 std from the previous command.
246244
- Build `librustdoc` and a bunch of other things with the stage2 compiler.
247245

248246
You almost never need to do this.
249247

250248
### Build specific components
251249

252250
If you are working on the standard library, you probably don't need to build
253-
the compiler unless you are planning to use a recently added nightly feature.
254-
Instead, you can just build using the bootstrap compiler.
251+
every other default component. Instead, you can build a specific component by
252+
providing its name, like this:
255253

256254
```bash
257-
./x build --stage 0 library
255+
./x build --stage 1 library
258256
```
259257

260-
If you choose the `library` profile when running `x setup`, you can omit `--stage 0` (it's the
258+
If you choose the `library` profile when running `x setup`, you can omit `--stage 1` (it's the
261259
default).
262260

263261
## Creating a rustup toolchain
@@ -271,7 +269,6 @@ you will likely need to build at some point; for example, if you want
271269
to run the entire test suite).
272270

273271
```bash
274-
rustup toolchain link stage0 build/host/stage0-sysroot # beta compiler + stage0 std
275272
rustup toolchain link stage1 build/host/stage1
276273
rustup toolchain link stage2 build/host/stage2
277274
```

‎src/doc/rustc-dev-guide/src/building/new-target.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ Look for existing targets to use as examples.
8585
After adding your target to the `rustc_target` crate you may want to add
8686
`core`, `std`, ... with support for your new target. In that case you will
8787
probably need access to some `target_*` cfg. Unfortunately when building with
88-
stage0 (the beta compiler), you'll get an error that the target cfg is
88+
stage0 (a precompiled compiler), you'll get an error that the target cfg is
8989
unexpected because stage0 doesn't know about the new target specification and
9090
we pass `--check-cfg` in order to tell it to check.
9191

‎src/doc/rustc-dev-guide/src/building/suggested.md‎

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -273,51 +273,15 @@ lets you use `cargo fmt`.
273273
[the section on vscode]: suggested.md#configuring-rust-analyzer-for-rustc
274274
[the section on rustup]: how-to-build-and-run.md?highlight=rustup#creating-a-rustup-toolchain
275275

276-
## Faster builds with `--keep-stage`.
277-
278-
Sometimes just checking whether the compiler builds is not enough. A common
279-
example is that you need to add a `debug!` statement to inspect the value of
280-
some state or better understand the problem. In that case, you don't really need
281-
a full build. By bypassing bootstrap's cache invalidation, you can often get
282-
these builds to complete very fast (e.g., around 30 seconds). The only catch is
283-
this requires a bit of fudging and may produce compilers that don't work (but
284-
that is easily detected and fixed).
285-
286-
The sequence of commands you want is as follows:
287-
288-
- Initial build: `./x build library`
289-
- As [documented previously], this will build a functional stage1 compiler as
290-
part of running all stage0 commands (which include building a `std`
291-
compatible with the stage1 compiler) as well as the first few steps of the
292-
"stage 1 actions" up to "stage1 (sysroot stage1) builds std".
293-
- Subsequent builds: `./x build library --keep-stage 1`
294-
- Note that we added the `--keep-stage 1` flag here
295-
296-
[documented previously]: ./how-to-build-and-run.md#building-the-compiler
297-
298-
As mentioned, the effect of `--keep-stage 1` is that we just _assume_ that the
299-
old standard library can be re-used. If you are editing the compiler, this is
300-
almost always true: you haven't changed the standard library, after all. But
301-
sometimes, it's not true: for example, if you are editing the "metadata" part of
302-
the compiler, which controls how the compiler encodes types and other states
303-
into the `rlib` files, or if you are editing things that wind up in the metadata
304-
(such as the definition of the MIR).
305-
306-
**The TL;DR is that you might get weird behavior from a compile when using
307-
`--keep-stage 1`** -- for example, strange [ICEs](../appendix/glossary.html#ice)
308-
or other panics. In that case, you should simply remove the `--keep-stage 1`
309-
from the command and rebuild. That ought to fix the problem.
310-
311-
You can also use `--keep-stage 1` when running tests. Something like this:
312-
313-
- Initial test run: `./x test tests/ui`
314-
- Subsequent test run: `./x test tests/ui --keep-stage 1`
315-
316-
### Iterating the standard library with `--keep-stage`
317-
318-
If you are making changes to the standard library, you can use `./x build
319-
--keep-stage 0 library` to iteratively rebuild the standard library without
320-
rebuilding the compiler.
276+
## Faster Builds with CI-rustc
277+
278+
If you are not working on the compiler, you often don't need to build the compiler tree.
279+
For example, you can skip building the compiler and only build the `library` tree or the
280+
tools under `src/tools`. To achieve that, you have to enable this by setting the `download-rustc`
281+
option in your configuration. This tells bootstrap to use the latest nightly compiler for `stage > 0`
282+
steps, meaning it will have two precompiled compilers: stage0 compiler and `download-rustc` compiler
283+
for `stage > 0` steps. This way, it will never need to build the in-tree compiler. As a result, your
284+
build time will be significantly reduced by not building the in-tree compiler.
321285

322286
## Using incremental compilation
323287

‎src/doc/rustc-dev-guide/src/tests/ci.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ kinds of builds (sets of jobs).
6666
### Pull Request builds
6767

6868
After each push to a pull request, a set of `pr` jobs are executed. Currently,
69-
these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `mingw-check` and
70-
`mingw-check-tidy` jobs, all running on Linux. These execute a relatively short
71-
(~30 minutes) and lightweight test suite that should catch common issues. More
69+
these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `mingw-check-1`, `mingw-check-2`
70+
and `mingw-check-tidy` jobs, all running on Linux. These execute a relatively short
71+
(~40 minutes) and lightweight test suite that should catch common issues. More
7272
specifically, they run a set of lints, they try to perform a cross-compile check
7373
build to Windows mingw (without producing any artifacts) and they test the
7474
compiler using a *system* version of LLVM. Unfortunately, it would take too many

0 commit comments

Comments
 (0)
This repository has been archived.