_break the stability guarantees_ of Rust: allowing use of `#![feature(...)]`
with a compiler that's not `nightly`. _Setting `RUSTC_BOOTSTRAP=1` should
never be used except when bootstrapping the compiler._
## Understanding stages of bootstrap
### Overview
This is a detailed look into the separate bootstrap stages.
The convention `./x` uses is that:
- A `--stage N` flag means to run the stage N compiler (`stageN/rustc`).
- A "stage N artifact" is a build artifact that is _produced_ by the stage N
compiler.
- The stage N+1 compiler is assembled from stage N *artifacts*. This process is
called _uplifting_.
#### Build artifacts
Anything you can build with `./x` is a _build artifact_. Build artifacts
include, but are not limited to:
- binaries, like `stage0-rustc/rustc-main`
- shared objects, like `stage0-sysroot/rustlib/libstd-6fae108520cf72fe.so`
- [rlib] files, like `stage0-sysroot/rustlib/libstd-6fae108520cf72fe.rlib`
- HTML files generated by rustdoc, like `doc/std`
#### Examples
- `./x test tests/ui` means to build the `stage1` compiler and run `compiletest`
on it. If you're working on the compiler, this is normally the test command
you want.
- `./x test --stage 0 library/std` means to run tests on the standard library
without building `rustc` from source ('build with `stage0`, then test the
artifacts'). If you're working on the standard library, this is normally the
test command you want.
- `./x build --stage 0` means to build with the stage0 `rustc`.
- `./x doc --stage 0` means to document using the stage0 `rustdoc`.
#### Examples of what *not* to do
- `./x test --stage 0 tests/ui` is not useful: it runs tests on the _beta_
compiler and doesn't build `rustc` from source. Use `test tests/ui` instead,
which builds `stage1` from source.
- `./x test --stage 0 compiler/rustc` builds the compiler but runs no tests:
it's running `cargo test -p rustc`, but `cargo` doesn't understand Rust's
tests. You shouldn't need to use this, use `test` instead (without arguments).
- `./x build --stage 0 compiler/rustc` builds the compiler, but does not build
`libstd` or even `libcore`. Most of the time, you'll want `./x build library`
instead, which allows compiling programs without needing to define lang items.
### Building vs. running
In short, _stage 0 uses the `stage0` compiler to create `stage0` artifacts which
will later be uplifted to be the stage1 compiler_.
In each stage, two major steps are performed:
1. `std` is compiled by the stage N compiler.
2. That `std` is linked to programs built by the stage N compiler, including the
stage N artifacts (stage N+1 compiler).
This is somewhat intuitive if one thinks of the stage N artifacts as "just"
another program we are building with the stage N compiler: `build --stage N
compiler/rustc` is linking the stage N artifacts to the `std` built by the stage
N compiler.
### Stages and `std`
Note that there are two `std` libraries in play here:
1. The library _linked_ to `stageN/rustc`, which was built by stage N-1 (stage
N-1 `std`)
2. The library _used to compile programs_ with `stageN/rustc`, which was built
by stage N (stage N `std`).
Stage N `std` is pretty much necessary for any useful work with the stage N
compiler. Without it, you can only compile programs with `#![no_core]` -- not
terribly useful!
The reason these need to be different is because they aren't necessarily
ABI-compatible: there could be new layout optimizations, changes to `MIR`, or
other changes to Rust metadata on `nightly` that aren't present in beta.
This is also where `--keep-stage 1 library/std` comes into play. Since most
changes to the compiler don't actually change the ABI, once you've produced a
`std` in `stage1`, you can probably just reuse it with a different compiler. If
the ABI hasn't changed, you're good to go, no need to spend time recompiling
that `std`. The flag `--keep-stage` simply instructs the build script to assumes
the previous compile is fine and copies those artifacts into the appropriate