cfg(bootstrap)
in compiler dependenciesThe 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.
#[cfg(bootstrap)]
Usually the use of #[cfg(bootstrap)]
in an external crate causes a warning:
warning: unexpected `cfg` condition name: `bootstrap` --> src/main.rs:1:7 | 1 | #[cfg(bootstrap)] | ^^^^^^^^^ | = help: expected names are: `docsrs`, `feature`, and `test` and 31 more = help: consider using a Cargo feature instead = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } = help: or consider adding `println!("cargo::rustc-check-cfg=cfg(bootstrap)");` to the top of the `build.rs` = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default
This warning can be silenced by adding these lines to the project's Cargo.toml
:
[lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] }
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.
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.
In this example it is possible to accept both the old and new behavior at the same time by disabling an error.
Now in the crate, use #[cfg(bootstrap)]
to use the old behavior, or #[cfg(not(bootstrap))]
to use the new behavior.
For compiler-builtins
this meant a version bump, in other cases it may be a git submodule update.
The updated crate can now be used. In this example that meant that the old behavior could be removed.