|
| 1 | +# Bootstrap in compiler dependencies |
| 2 | + |
| 3 | +The rust compiler uses some external crates that can run into cyclic dependencies with the compiler itself: the compiler needs an updated crate to build, but the crate needs an updated compiler. This page describes how `#[cfg(bootstrap)]` can be used to break this cycle. |
| 4 | + |
| 5 | +## Enabling `#[cfg(bootstrap)]` |
| 6 | + |
| 7 | +Usually the use of `#[cfg(bootstrap)]` in an external crate causes a warning: |
| 8 | + |
| 9 | +``` |
| 10 | +warning: unexpected `cfg` condition name: `bootstrap` |
| 11 | + --> src/main.rs:1:7 |
| 12 | + | |
| 13 | +1 | #[cfg(bootstrap)] |
| 14 | + | ^^^^^^^^^ |
| 15 | + | |
| 16 | + = help: expected names are: `docsrs`, `feature`, and `test` and 31 more |
| 17 | + = help: consider using a Cargo feature instead |
| 18 | + = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: |
| 19 | + [lints.rust] |
| 20 | + unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } |
| 21 | + = help: or consider adding `println!("cargo::rustc-check-cfg=cfg(bootstrap)");` to the top of the `build.rs` |
| 22 | + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration |
| 23 | + = note: `#[warn(unexpected_cfgs)]` on by default |
| 24 | +``` |
| 25 | + |
| 26 | +This warning can be silenced by adding these lines to the project's `Cargo.toml`: |
| 27 | + |
| 28 | +```toml |
| 29 | +[lints.rust] |
| 30 | +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } |
| 31 | +``` |
| 32 | + |
| 33 | +Now `#[cfg(bootstrap)]` can be used in the crate just like it can be in the compiler: when the bootstrap compiler is used, code annotated with `#[cfg(bootstrap)]` is compiled, otherwise code annotated with `#[cfg(not(bootstrap))]` is compiled. |
| 34 | + |
| 35 | +## The update dance |
| 36 | + |
| 37 | +As a concrete example we'll use a change where the `#[naked]` attribute was made into an unsafe attribute, which caused a cyclic dependency with the `compiler-builtins` crate. |
| 38 | + |
| 39 | +### Step 1: accept the new behavior in the compiler ([#139797](https://github.com/rust-lang/rust/pull/139797)) |
| 40 | + |
| 41 | +In this example it is possible to accept both the old and new behavior at the same time by disabling an error. |
| 42 | + |
| 43 | +### Step 2: update the crate ([#821](https://github.com/rust-lang/compiler-builtins/pull/821)) |
| 44 | + |
| 45 | +Now in the crate, use `#[cfg(bootstrap)]` to use the old behavior, or `#[cfg(not(bootstrap))]` to use the new behavior. |
| 46 | + |
| 47 | +### Step 3: update the crate version used by the compiler ([#139934](https://github.com/rust-lang/rust/pull/139934)) |
| 48 | + |
| 49 | +For `compiler-builtins` this meant a version bump, in other cases it may be a git submodule update. |
| 50 | + |
| 51 | +### Step 4: remove the old behavior from the compiler ([#139753](https://github.com/rust-lang/rust/pull/139753)) |
| 52 | + |
| 53 | +The updated crate can now be used. In this example that meant that the old behavior could be removed. |
0 commit comments