惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Security @ Cisco Blogs
小众软件
小众软件
D
Docker
博客园_首页
A
About on SuperTechFans
P
Privacy International News Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
A
Arctic Wolf
Spread Privacy
Spread Privacy
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
Latest news
Latest news
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
The Exploit Database - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
大猫的无限游戏
大猫的无限游戏
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
K
Kaspersky official blog
V2EX - 技术
V2EX - 技术
SecWiki News
SecWiki News
U
Unit 42
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LINUX DO - 热门话题
S
Security Affairs
Y
Y Combinator Blog
aimingoo的专栏
aimingoo的专栏
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
博客园 - 【当耐特】
The GitHub Blog
The GitHub Blog
T
Tenable Blog
W
WeLiveSecurity
Cloudbric
Cloudbric
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
Google Developers Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
Netflix TechBlog - Medium
F
Full Disclosure
N
News and Events Feed by Topic
D
DataBreaches.Net
P
Proofpoint News Feed
B
Blog RSS Feed
B
Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org

Rust Blog

Security Advisory for Cargo (CVE-2026-5223) | Rust Blog Security Advisory for Cargo (CVE-2026-5222) | Rust Blog Project goals update — April 2026 (end of 2025H2) | Rust Blog Rust is participating in Outreachy | Rust Blog Raising the baseline for the `nvptx64-nvidia-cuda` target | Rust Blog Announcing Google Summer of Code 2026 selected projects | Rust Blog Announcing Rust 1.95.0 | Rust Blog docs.rs: building fewer targets by default | Rust Blog Changes to WebAssembly targets and handling undefined symbols | Rust Blog Announcing Rust 1.94.1 | Rust Blog Security advisory for Cargo | Rust Blog What we heard about Rust's challenges | Rust Blog Call for Testing: Build Dir Layout v2 | Rust Blog Announcing rustup 1.29.0 | Rust Blog Announcing Rust 1.94.0 | Rust Blog 2025 State of Rust Survey Results | Rust Blog Rust debugging survey 2026 | Rust Blog Update on the October 15, 2018 incident on crates.io Announcing Rust 1.29.2 Announcing Rust 1.29 Announcing Rust 1.28 What is Rust 2018? Announcing Rust 1.27.2 Announcing Rust 1.27.1 Security Advisory for rustdoc Announcing Rust 1.27 Announcing Rust 1.26.2 Announcing Rust 1.26.1 Rust turns three Announcing Rust 1.26 The Rust Team All Hands in Berlin: a Recap Increasing Rust’s Reach 2018 Announcing Rust 1.25 Rust's 2018 roadmap Announcing Rust 1.24.1 Announcing Rust 1.24 The 2018 Rust Event Lineup Announcing Rust 1.23 New Year's Rust: A Call for Community Blogposts Rust in 2017: what we achieved Announcing Rust 1.22 (and 1.22.1) Fearless Concurrency in Firefox Quantum Announcing Rust 1.21 impl Future for Rust Rust 2017 Survey Results Announcing Rust 1.20 Announcing Rust 1.19 The 2017 Rust Conference Lineup Rust's 2017 roadmap, six months in Increasing Rust’s Reach Announcing Rust 1.18 Two years of Rust The Rust Libz Blitz Launching the 2017 State of Rust Survey Announcing Rust 1.17 Announcing Rust 1.16 Rust's language ergonomics initiative Announcing Rust 1.15.1 Rust's 2017 roadmap Announcing Rust 1.15 Announcing Rust 1.14 Announcing the First Underhanded Rust Contest Announcing Rust 1.13 Announcing Rust 1.12.1 Announcing Rust 1.12 Incremental Compilation Announcing Rust 1.11 Shape of errors to come The 2016 Rust Conference Lineup Announcing Rust 1.10 State of Rust Survey 2016 Announcing Rust 1.9 One year of Rust Taking Rust everywhere with rustup Launching the 2016 State of Rust Survey Cargo: predictable dependency management Introducing MIR Announcing Rust 1.8 Announcing Rust 1.7 Announcing Rust 1.6 Announcing Rust 1.5 Announcing Rust 1.4 Announcing Rust 1.3 Rust in 2016 Announcing Rust 1.2 Rust 1.1 stable, the Community Subteam, and RustCamp Announcing Rust 1.0 Abstraction without overhead: traits in Rust Rust Once, Run Everywhere Mixing matching, mutation, and moves in Rust Fearless Concurrency with Rust Announcing Rust 1.0 Beta Announcing Rust 1.0.0.alpha.2 Rust 1.0: status report and final timeline Announcing Rust 1.0 Alpha Rust 1.0: Scheduling the trains Yehuda Katz and Steve Klabnik are joining the Rust Core Team Cargo: Rust's community crate host Stability as a Deliverable Road to Rust 1.0
Redesigning the Initial Bootstrap Sequence | Inside Rust Blog
Jieyou Xu on behalf of the Bootstrap team · 2025-05-29 · via Rust Blog

Revisions:

  • (2025-05-30) This blog post was edited to clarify distribution packagers will not be observably impacted (i.e. distribution packages will still be able to build N + 1 version of Rust using version N of Rust).

This blog post accompanies an upcoming major change to the rust-lang/rust build system (see also Major Change Proposal 619). This will have no impact on the distributed artifacts from rust-lang/rust, but the way we build those artifacts is changing.

This blog post focuses on motivation for the change and attempts to build a mental model for how the system works, rather than deep diving on workflow changes. See the rustc-dev-guide for details on how you might need to change your workflow with these changes. Note that rustc-dev-guide pages will have updated content once the implementation PR merges.

TL;DR: What is being changed?

We are redesigning the bootstrap sequence for the Rust toolchain. The standard library will move from supporting being built by both the previous toolchain version and the current version to only supporting the current version. This does not change the artifacts we distribute to end users of Rust.

The Rust toolchain as a whole, both currently and after this change, supports being built with just two minor versions of Rust: the previous version and its own version. For example, Rust 1.85.1 requires one of 1.84.0, 1.85.0, or 1.85.1 toolchains to build its source code into the 1.85.1 distributed artifacts.

In other words, distribution packagers are not observably affected, it is only the workflows of contributors who work on the compiler and standard library that will be impacted.

Current bootstrap sequence

Current stage 0 bootstrap sequence

Redesigned bootstrap sequence

Redesigned stage 0 bootstrap sequence

The following section is a quick primer on the concept of bootstrapping and the terminology we use in this blog post.

A quick primer on bootstrapping and terminology used in this blog post

This section is intended to explain some basic bootstrapping concepts to make it easier for contributors to understand the upcoming bootstrap changes. You can skip this section if you are already familiar with the bootstrap build system itself.

What is bootstrapping?

Bootstrapping is the process of producing a newer version of a compiler with an older version of itself. Usually, bootstrap processes involve the concept of stages, where a compiler and associated artifacts from a stage is used to build the compiler of the next stage. For example, a stage 2 compiler is built from a stage 1 compiler and associated stage 1 artifacts. The stage number is named after the compiler in question.

Bootstrapping rustc

Building a C++ compiler toolchain like gcc or clang doesn't usually involving building their standard libraries from source, but instead will link against a pre-built standard library across all bootstrap stages. Typically, this specified standard library is the system standard library.1

The Rust toolchain as a whole, both currently and after this change, supports being built with just two minor versions of Rust: the previous version and its own version. For example, Rust 1.85.1 requires one of 1.84.0, 1.85.0, or 1.85.1 toolchains to build its source code into the 1.85.1 distributed artifacts.

Rust has historically always built the majority of in-tree source code against the in-tree standard library's API. This meant that the in-tree copy of the standard library had to support being built with both the previous release (e.g., 1.84) and the new release (e.g., 1.85), requiring extensive cfg(bootstrap) annotations to be compatible with the unstable API of the compiler (primarily changes in intrinsics and lang items).

The choice to require std to be built with two different compiler toolchains is largely historical. We don't have specific rationale available, but expect it to have made more sense when the standard library API was rapidly evolving and the compiler was unable to use crates.io dependencies for functionality.

Terminology

Naive bootstrap stage

Let us call these intra-stage steps of stage N - 1 compiler building stage N - 1 standard library a bootstrap sequence, i.e. the sequence of intra-stage steps involved in producing stage N - 1 artifacts required to build the stage N compiler.

Bootstrap sequence

We must also have a base case, a starting compiler, to build newer compilers with. Indeed, the initial compiler is also called the stage 0 compiler. The initial bootstrap stage is called stage 0.

Motivation

But the naive model we presented above isn't complete.

Rust has elected a design choice where the compiler, rustc, and the standard library ("std") are tightly coupled. Intrinsics and lang items form a broad interface between the compiler and the standard library. When intrinsics or lang items are modified, both sides need to be adjusted.

Currently, the standard library must support being built with two different compilers, the in-tree compiler and the initial stage 0 compiler2. All such changes to intrinsics and lang items thus need to use cfg(bootstrap) to gate code that can be built by the in-tree compiler vs the stage 0 compiler. This causes a lot of churn for contributors wanting to introduce, modify or remove intrinsics and lang items (particularly when creating new releases).

The stage 0 bootstrap sequence redesign aims to mitigate such churn and implementation complexity in the standard library by having the standard library only support one version of the compiler.

To better understand this redesign, we will:

  1. Explain how the current stage 0 bootstrapping sequence works, and
  2. Explain how the new stage 0 bootstrapping sequence works after the redesign, and
  3. Explain the benefits of the redesigned stage 0 bootstrapping sequence.

The current stage 0 bootstrap sequence

Current stage 0 bootstrap sequence

Currently, bootstrap downloads a pre-built beta rustc as the initial compiler (stage 0 rustc).

  • To produce a stage 1 rustc, we need to produce a stage 0 std. This stage 0 std is built from in-tree standard library sources with cfg(bootstrap) active.
  • To produce a stage 2 rustc, we need to produce a stage 1 std. However, this is where things get weird. The stage 1 std is built from the same in-tree standard library sources (but with cfg(bootstrap) inactive). This is what we meant by "the standard library has to support being buildable by two compiler versions."

The redesigned stage 0 bootstrap sequence

Redesigned stage 0 bootstrap sequence

In the redesigned stage 0 bootstrapping sequence we instead download both the pre-built beta rustc as the stage 0 compiler, and the pre-built beta std as the stage 0 std, instead of building stage 0 std from in-tree sources.

  • When producing a stage 1 rustc, we already have the stage 0 std (as it is the pre-built std).
  • When producing a stage 2 rustc, the stage 1 std is then the std built from in-tree std sources with the stage 1 rustc.

Why is the redesigned stage 0 bootstrap sequence better?

There are several benefits of the redesigned stage 0 bootstrap sequence:

  1. We no longer have to use cfg(bootstrap) in the standard library sources for intrinsics and lang items to distinguish when being built by the beta rustc vs the in-tree rustc, because the standard library now only has to be buildable by exactly one compiler version (the current stage rustc).
  2. Rebasing no longer has to rebuild everything. As the standard library is now built after the compiler instead of before, all dependencies and compiler crates that are unmodified can be cached when switching git branches. It's only necessary to rebuild everything after bootstrap bumps every 6 weeks as part of the release cycle.
  3. Modifying the standard library no longer has to rebuild everything. After the redesign, it is now possible to add documentation comments to functions in the standard library without having to rebuild the compiler and then also rebuild std a second time. --keep-stage-std=0 is no longer needed.
  4. It aligns better with how other rust programs are built. We no longer have a "strange" setup where the stage 1 compiler was built from a beta rustc with an in-tree std. Now, the stage 1 compiler is built from a beta rustc and a beta std.

In terms of bootstrap invocations and bootstrap config, what does this redesign mean?

The minimum stage to check, build and test the standard library is now stage 1. ./x {check,build,test} library --stage=0 are now no-ops; switch to --stage 1 instead. --keep-stage-std=0 is a no-op.

For profile = "library" users, like aforementioned, the default check, build, and test stage are now bumped to 1. download-rustc = "if-unchanged" is enabled by default, which downloads a pre-built CI rustc instead of building the compiler if there are no compiler changes, allowing you to build the standard library without building the compiler.

What does this mean for contributors working on the standard library and the compiler?

  • Contributors will now no longer need to use cfg(bootstrap) for intrinsics and lang items.
  • Contributors may (rarely) need to use cfg(bootstrap) in compiler code if they wish to experiment with unstable library features 3

Frequently asked questions (FAQs)

Doesn't this just shift cfg(bootstrap) from library code to compiler code?

Not quite. cfg(bootstrap) usage in standard library code for using new intrinsics / lang items (as in the current bootstrap sequence) is much more common than potential cfg(bootstrap) usage in compiler code for experimenting with unstable library features (as in the redesigned bootstrap sequence). This is because the standard library must be changed for new compiler-provided lang items and intrinsics, but the compiler does not (need to) depend on recently added standard library APIs.

Additionally, the compiler only needs to add cfg(bootstrap) for anything in the standard library that has changed its unstable API and which is used in the compiler.

Example: Implementing a trait solving feature which requires adding core lang items

This will involve adding a new lang item in the compiler (e.g. compiler/rustc_hir/src/lang_items.rs) and the standard library. Prior to the redesign, the usage of the lang item in the standard library requires cfg(not(bootstrap)) since the beta compiler does not know about the new lang item. Recall that the standard library has to support being built by both the beta compiler and the in-tree compiler! After the redesign, cfg(not(bootstrap)) usage of the lang item in the standard library is not needed since the standard library is only buildable by the in-tree compiler that adds the new lang item.

A stage 2 compiler is not required to test the new feature, as the stage 1 library using the lang item is built by the stage 1 compiler, which is the compiler where the new lang item is added!

Will this affect distribution packagers?

No, this change will not have observable changes for distribution packagers. Distribution packagers will still be able to build e.g. 1.85.0 distribution artifacts with a 1.84.0, 1.84.1 or 1.85.0 toolchain.

Questions, feedback, bugs?

You can leave a comment in the zulip support thread for the initial bootstrap sequence redesign effort

  1. Much of this is adapted from jyn's excellent blog post Why is Rust's build system uniquely hard to use?.

  2. For the vast majority of contributors, the stage 0 "initial" compiler is going to be the beta compiler. However, it is possible to override the initial compiler, such as when further optimizing a compiler through PGO/BOLT. In this blog post, we make a simplifying assumption that the stage 0 compiler is the beta compiler, even though this is not universally true.

  3. Newly added unstable library feature may need to wait until a beta bump before it is usable by the compiler.