Skip to content

Commit 3827139

Browse files
committed
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
2 parents e0883a2 + 34d5ce5 commit 3827139

File tree

51 files changed

+289
-327
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+289
-327
lines changed

compiler/rustc_lint/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
2222
// tidy-alphabetical-start
2323
#![allow(internal_features)]
24+
#![cfg_attr(bootstrap, feature(extract_if))]
2425
#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141
2526
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
2627
#![doc(rust_logo)]

compiler/rustc_metadata/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// tidy-alphabetical-start
22
#![allow(internal_features)]
3+
#![cfg_attr(bootstrap, feature(extract_if))]
34
#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141
45
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
56
#![doc(rust_logo)]

compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#![allow(rustc::diagnostic_outside_of_impl)]
3030
#![allow(rustc::potential_query_instability)]
3131
#![allow(rustc::untranslatable_diagnostic)]
32+
#![cfg_attr(bootstrap, feature(extract_if))]
3233
#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141
3334
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
3435
#![doc(rust_logo)]

compiler/rustc_resolve/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#![allow(internal_features)]
1111
#![allow(rustc::diagnostic_outside_of_impl)]
1212
#![allow(rustc::untranslatable_diagnostic)]
13+
#![cfg_attr(bootstrap, feature(extract_if))]
1314
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1415
#![doc(rust_logo)]
1516
#![feature(assert_matches)]

compiler/rustc_serialize/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// tidy-alphabetical-start
44
#![allow(internal_features)]
55
#![allow(rustc::internal)]
6+
#![cfg_attr(bootstrap, feature(ptr_sub_ptr))]
67
#![cfg_attr(test, feature(test))]
78
#![doc(
89
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",

compiler/rustc_serialize/src/opaque.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -280,13 +280,27 @@ impl<'a> MemDecoder<'a> {
280280
#[inline]
281281
pub fn len(&self) -> usize {
282282
// SAFETY: This recovers the length of the original slice, only using members we never modify.
283-
unsafe { self.end.offset_from_unsigned(self.start) }
283+
#[cfg(bootstrap)]
284+
unsafe {
285+
return self.end.sub_ptr(self.start);
286+
}
287+
#[cfg(not(bootstrap))]
288+
unsafe {
289+
self.end.offset_from_unsigned(self.start)
290+
}
284291
}
285292

286293
#[inline]
287294
pub fn remaining(&self) -> usize {
288295
// SAFETY: This type guarantees current <= end.
289-
unsafe { self.end.offset_from_unsigned(self.current) }
296+
#[cfg(bootstrap)]
297+
unsafe {
298+
return self.end.sub_ptr(self.current);
299+
}
300+
#[cfg(not(bootstrap))]
301+
unsafe {
302+
self.end.offset_from_unsigned(self.current)
303+
}
290304
}
291305

292306
#[cold]
@@ -400,7 +414,14 @@ impl<'a> Decoder for MemDecoder<'a> {
400414
#[inline]
401415
fn position(&self) -> usize {
402416
// SAFETY: This type guarantees start <= current
403-
unsafe { self.current.offset_from_unsigned(self.start) }
417+
#[cfg(bootstrap)]
418+
unsafe {
419+
return self.current.sub_ptr(self.start);
420+
}
421+
#[cfg(not(bootstrap))]
422+
unsafe {
423+
self.current.offset_from_unsigned(self.start)
424+
}
404425
}
405426
}
406427

compiler/rustc_span/src/analyze_source_file.rs

+14
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,30 @@ cfg_match! {
8383

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.
86+
#[cfg(bootstrap)]
87+
let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) };
88+
#[cfg(not(bootstrap))]
8689
let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0));
90+
8791
// Create a bit mask from the comparison results.
92+
#[cfg(bootstrap)]
93+
let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) };
94+
#[cfg(not(bootstrap))]
8895
let multibyte_mask = _mm_movemask_epi8(multibyte_test);
8996

9097
// If the bit mask is all zero, we only have ASCII chars here:
9198
if multibyte_mask == 0 {
9299
assert!(intra_chunk_offset == 0);
93100

94101
// Check for newlines in the chunk
102+
#[cfg(bootstrap)]
103+
let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) };
104+
#[cfg(not(bootstrap))]
95105
let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8));
106+
107+
#[cfg(bootstrap)]
108+
let mut newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) };
109+
#[cfg(not(bootstrap))]
96110
let mut newlines_mask = _mm_movemask_epi8(newlines_test);
97111

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

compiler/rustc_trait_selection/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#![allow(internal_features)]
1515
#![allow(rustc::diagnostic_outside_of_impl)]
1616
#![allow(rustc::untranslatable_diagnostic)]
17+
#![cfg_attr(bootstrap, feature(extract_if))]
1718
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1819
#![doc(rust_logo)]
1920
#![feature(assert_matches)]

library/alloc/src/collections/btree/set_val.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub(super) struct SetValZST;
99
/// Returns `true` only for type `SetValZST`, `false` for all other types (blanket implementation).
1010
/// `TypeId` requires a `'static` lifetime, use of this trait avoids that restriction.
1111
///
12-
/// [`TypeId`]: std::any::TypeId
12+
/// [`TypeId`]: core::any::TypeId
1313
pub(super) trait IsSetVal {
1414
fn is_set_val() -> bool;
1515
}

library/core/src/clone.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ pub macro Clone($item:item) {
216216
/// Use closures allow captured values to be automatically used.
217217
/// This is similar to have a closure that you would call `.use` over each captured value.
218218
#[unstable(feature = "ergonomic_clones", issue = "132290")]
219-
#[cfg_attr(not(bootstrap), lang = "use_cloned")]
219+
#[lang = "use_cloned"]
220220
pub trait UseCloned: Clone {
221221
// Empty.
222222
}

library/core/src/fmt/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,7 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argume
15461546
#[cfg(bootstrap)]
15471547
unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option<u16> {
15481548
match *cnt {
1549-
rt::Count::Is(n) => Some(n as u16),
1549+
rt::Count::Is(n) => Some(n),
15501550
rt::Count::Implied => None,
15511551
rt::Count::Param(i) => {
15521552
debug_assert!(i < args.len());

library/core/src/fmt/rt.rs

-4
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@ pub enum Alignment {
5151
#[derive(Copy, Clone)]
5252
pub enum Count {
5353
/// Specified with a literal number, stores the value
54-
#[cfg(bootstrap)]
55-
Is(usize),
56-
/// Specified with a literal number, stores the value
57-
#[cfg(not(bootstrap))]
5854
Is(u16),
5955
/// Specified using `$` and `*` syntaxes, stores the index into `args`
6056
Param(usize),

library/core/src/intrinsics/mod.rs

-48
Original file line numberDiff line numberDiff line change
@@ -2307,41 +2307,17 @@ pub unsafe fn truncf128(x: f128) -> f128;
23072307
/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
23082308
#[rustc_intrinsic]
23092309
#[rustc_nounwind]
2310-
#[cfg(not(bootstrap))]
23112310
pub fn round_ties_even_f16(x: f16) -> f16;
23122311

2313-
/// To be removed on next bootstrap bump.
2314-
#[cfg(bootstrap)]
2315-
pub fn round_ties_even_f16(x: f16) -> f16 {
2316-
#[rustc_intrinsic]
2317-
#[rustc_nounwind]
2318-
unsafe fn rintf16(x: f16) -> f16;
2319-
2320-
// SAFETY: this intrinsic isn't actually unsafe
2321-
unsafe { rintf16(x) }
2322-
}
2323-
23242312
/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even
23252313
/// least significant digit.
23262314
///
23272315
/// The stabilized version of this intrinsic is
23282316
/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
23292317
#[rustc_intrinsic]
23302318
#[rustc_nounwind]
2331-
#[cfg(not(bootstrap))]
23322319
pub fn round_ties_even_f32(x: f32) -> f32;
23332320

2334-
/// To be removed on next bootstrap bump.
2335-
#[cfg(bootstrap)]
2336-
pub fn round_ties_even_f32(x: f32) -> f32 {
2337-
#[rustc_intrinsic]
2338-
#[rustc_nounwind]
2339-
unsafe fn rintf32(x: f32) -> f32;
2340-
2341-
// SAFETY: this intrinsic isn't actually unsafe
2342-
unsafe { rintf32(x) }
2343-
}
2344-
23452321
/// Provided for compatibility with stdarch. DO NOT USE.
23462322
#[inline(always)]
23472323
pub unsafe fn rintf32(x: f32) -> f32 {
@@ -2355,20 +2331,8 @@ pub unsafe fn rintf32(x: f32) -> f32 {
23552331
/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
23562332
#[rustc_intrinsic]
23572333
#[rustc_nounwind]
2358-
#[cfg(not(bootstrap))]
23592334
pub fn round_ties_even_f64(x: f64) -> f64;
23602335

2361-
/// To be removed on next bootstrap bump.
2362-
#[cfg(bootstrap)]
2363-
pub fn round_ties_even_f64(x: f64) -> f64 {
2364-
#[rustc_intrinsic]
2365-
#[rustc_nounwind]
2366-
unsafe fn rintf64(x: f64) -> f64;
2367-
2368-
// SAFETY: this intrinsic isn't actually unsafe
2369-
unsafe { rintf64(x) }
2370-
}
2371-
23722336
/// Provided for compatibility with stdarch. DO NOT USE.
23732337
#[inline(always)]
23742338
pub unsafe fn rintf64(x: f64) -> f64 {
@@ -2382,20 +2346,8 @@ pub unsafe fn rintf64(x: f64) -> f64 {
23822346
/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
23832347
#[rustc_intrinsic]
23842348
#[rustc_nounwind]
2385-
#[cfg(not(bootstrap))]
23862349
pub fn round_ties_even_f128(x: f128) -> f128;
23872350

2388-
/// To be removed on next bootstrap bump.
2389-
#[cfg(bootstrap)]
2390-
pub fn round_ties_even_f128(x: f128) -> f128 {
2391-
#[rustc_intrinsic]
2392-
#[rustc_nounwind]
2393-
unsafe fn rintf128(x: f128) -> f128;
2394-
2395-
// SAFETY: this intrinsic isn't actually unsafe
2396-
unsafe { rintf128(x) }
2397-
}
2398-
23992351
/// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero.
24002352
///
24012353
/// The stabilized version of this intrinsic is

library/core/src/macros/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1753,7 +1753,6 @@ pub(crate) mod builtin {
17531753
reason = "`type_alias_impl_trait` has open design concerns"
17541754
)]
17551755
#[rustc_builtin_macro]
1756-
#[cfg(not(bootstrap))]
17571756
pub macro define_opaque($($tt:tt)*) {
17581757
/* compiler built-in */
17591758
}

library/core/src/pat.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ macro_rules! pattern_type {
2525
)]
2626
pub trait RangePattern {
2727
/// Trait version of the inherent `MIN` assoc const.
28-
#[cfg_attr(not(bootstrap), lang = "RangeMin")]
28+
#[lang = "RangeMin"]
2929
const MIN: Self;
3030

3131
/// Trait version of the inherent `MIN` assoc const.
32-
#[cfg_attr(not(bootstrap), lang = "RangeMax")]
32+
#[lang = "RangeMax"]
3333
const MAX: Self;
3434

3535
/// A compile-time helper to subtract 1 for exclusive ranges.
36-
#[cfg_attr(not(bootstrap), lang = "RangeSub")]
36+
#[lang = "RangeSub"]
3737
#[track_caller]
3838
fn sub_one(self) -> Self;
3939
}

library/core/src/prelude/v1.rs

-1
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,4 @@ pub use crate::macros::builtin::deref;
117117
issue = "63063",
118118
reason = "`type_alias_impl_trait` has open design concerns"
119119
)]
120-
#[cfg(not(bootstrap))]
121120
pub use crate::macros::builtin::define_opaque;

library/std/src/backtrace.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ mod helper {
432432
use super::*;
433433
pub(super) type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync + UnwindSafe;
434434

435-
#[cfg_attr(not(bootstrap), define_opaque(LazyResolve))]
435+
#[define_opaque(LazyResolve)]
436436
pub(super) fn lazy_resolve(mut capture: Capture) -> LazyResolve {
437437
move || {
438438
// Use the global backtrace lock to synchronize this as it's a

library/std/src/prelude/v1.rs

-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ pub use core::prelude::v1::deref;
109109
issue = "63063",
110110
reason = "`type_alias_impl_trait` has open design concerns"
111111
)]
112-
#[cfg(not(bootstrap))]
113112
pub use core::prelude::v1::define_opaque;
114113

115114
// The file so far is equivalent to core/src/prelude/v1.rs. It is duplicated

src/bootstrap/defaults/bootstrap.library.toml

+7-6
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

+9
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

+15-11
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,

0 commit comments

Comments
 (0)