summaryrefslogtreecommitdiffstats
path: root/src/doc/rustc-dev-guide
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /src/doc/rustc-dev-guide
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/doc/rustc-dev-guide')
-rw-r--r--src/doc/rustc-dev-guide/.mailmap5
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md3
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md2
-rw-r--r--src/doc/rustc-dev-guide/src/compiler-team.md8
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics.md9
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/lintstore.md33
-rw-r--r--src/doc/rustc-dev-guide/src/feature-gates.md10
-rw-r--r--src/doc/rustc-dev-guide/src/getting-started.md14
-rw-r--r--src/doc/rustc-dev-guide/src/guides/editions.md336
-rw-r--r--src/doc/rustc-dev-guide/src/implementing_new_features.md4
-rw-r--r--src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md24
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/arm.md3
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md3
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/llvm.md3
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/risc-v.md3
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/windows.md3
-rw-r--r--src/doc/rustc-dev-guide/src/tests/compiletest.md47
-rw-r--r--src/doc/rustc-dev-guide/src/tests/running.md33
-rw-r--r--src/doc/rustc-dev-guide/src/traits/canonicalization.md260
-rw-r--r--src/doc/rustc-dev-guide/src/walkthrough.md2
21 files changed, 728 insertions, 79 deletions
diff --git a/src/doc/rustc-dev-guide/.mailmap b/src/doc/rustc-dev-guide/.mailmap
new file mode 100644
index 000000000..1a1f6ffb6
--- /dev/null
+++ b/src/doc/rustc-dev-guide/.mailmap
@@ -0,0 +1,5 @@
+Jynn Nelson <github@jyn.dev> <jyn514@gmail.com>
+Jynn Nelson <github@jyn.dev> <joshua@yottadb.com>
+Jynn Nelson <github@jyn.dev> <jyn.nelson@redjack.com>
+Jynn Nelson <github@jyn.dev> <jnelson@cloudflare.com>
+Jynn Nelson <github@jyn.dev>
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index 4a7fd2b77..e484b6af6 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -56,6 +56,7 @@
- [RISC-V](notification-groups/risc-v.md)
- [Windows](notification-groups/windows.md)
- [Licenses](./licenses.md)
+- [Editions](guides/editions.md)
# High-level Compiler Architecture
@@ -123,6 +124,7 @@
- [Lowering to logic](./traits/lowering-to-logic.md)
- [Goals and clauses](./traits/goals-and-clauses.md)
- [Canonical queries](./traits/canonical-queries.md)
+ - [Canonicalization](./traits/canonicalization.md)
- [Next-gen trait solving](./solve/trait-solving.md)
- [Invariants of the type system](./solve/invariants.md)
- [The solver](./solve/the-solver.md)
@@ -130,6 +132,7 @@
- [Coinduction](./solve/coinduction.md)
- [Proof trees](./solve/proof-trees.md)
- [Normalization](./solve/normalization.md)
+ - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md)
- [Type checking](./type-checking.md)
- [Method Lookup](./method-lookup.md)
- [Variance](./variance.md)
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping.md b/src/doc/rustc-dev-guide/src/building/bootstrapping.md
index 936c75f36..1f66f08f3 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping.md
@@ -29,7 +29,7 @@ Note that this documentation mostly covers user-facing information. See
- Stage 2: the truly current compiler
- Stage 3: the same-result test
-Compiling `rustc` is done in stages. Here's a diagram, adapted from Joshua Nelson's
+Compiling `rustc` is done in stages. Here's a diagram, adapted from Jynn Nelson's
[talk on bootstrapping][rustconf22-talk] at RustConf 2022, with detailed explanations below.
The `A`, `B`, `C`, and `D` show the ordering of the stages of bootstrapping.
diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
index 1012e94fd..253a94956 100644
--- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
+++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
@@ -293,7 +293,7 @@ For example, if your host platform is `x86_64-unknown-linux-gnu`
and your cross-compilation target is `wasm32-wasi`, you can build with:
```bash
-./x build --target x86_64-unknown-linux-gnu --target wasm32-wasi
+./x build --target x86_64-unknown-linux-gnu,wasm32-wasi
```
Note that if you want the resulting compiler to be able to build crates that
diff --git a/src/doc/rustc-dev-guide/src/compiler-team.md b/src/doc/rustc-dev-guide/src/compiler-team.md
index d5ba78c77..9922ee7dd 100644
--- a/src/doc/rustc-dev-guide/src/compiler-team.md
+++ b/src/doc/rustc-dev-guide/src/compiler-team.md
@@ -17,15 +17,15 @@ Currently the compiler team chats in Zulip:
with rustc development, or [`t-compiler/meetings`][zulip-meetings],
where the team holds their weekly triage and steering meetings.
-## Expert map
+## Reviewers
If you're interested in figuring out who can answer questions about a
particular part of the compiler, or you'd just like to know who works on what,
-check out our [experts directory][experts].
+check out [triagebot.toml's assign section][map].
It contains a listing of the various parts of the compiler and a list of people
-who are experts on each one.
+who are reviewers of each part.
-[experts]: https://github.com/rust-lang/compiler-team/blob/master/content/experts/map.toml
+[map]: https://github.com/rust-lang/rust/blob/master/triagebot.toml
## Rust compiler meeting
diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md
index 9f4245f28..f21bae40f 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics.md
@@ -523,7 +523,7 @@ are:
- Early lint pass: Works on [AST nodes] after [macro expansion] and name
resolution, just before [HIR lowering]. These lints are for purely
syntactical lints.
- - Example: The [`unsued_parens`] lint checks for parenthesized-expressions
+ - Example: The [`unused_parens`] lint checks for parenthesized-expressions
in situations where they are not needed, like an `if` condition.
- Late lint pass: Works on [HIR nodes], towards the end of [analysis] (after
@@ -558,7 +558,7 @@ compiler](#linting-early-in-the-compiler).
[macro expansion]: macro-expansion.md
[analysis]: part-4-intro.md
[`keyword_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#keyword-idents
-[`unsued_parens`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unused-parens
+[`unused_parens`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unused-parens
[`invalid_value`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#invalid-value
[`arithmetic_overflow`]: https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#arithmetic-overflow
[`unused_mut`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unused-mut
@@ -572,7 +572,6 @@ generally based on how they are registered.
- *Built-in* lints are defined inside the compiler source.
- *Driver-registered* lints are registered when the compiler driver is created
by an external driver. This is the mechanism used by Clippy, for example.
-- *Plugin* lints are registered by the [deprecated plugin system].
- *Tool* lints are lints with a path prefix like `clippy::` or `rustdoc::`.
- *Internal* lints are the `rustc::` scoped tool lints that only run on the
rustc source tree itself and are defined in the compiler source like a
@@ -581,7 +580,6 @@ generally based on how they are registered.
More information about lint registration can be found in the [LintStore]
chapter.
-[deprecated plugin system]: https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html
[LintStore]: diagnostics/lintstore.md
### Declaring a lint
@@ -691,6 +689,8 @@ declare_lint! {
This makes the `ANONYMOUS_PARAMETERS` lint allow-by-default in the 2015 edition
but warn-by-default in the 2018 edition.
+See [Edition-specific lints](../guides/editions.md#edition-specific-lints) for more information.
+
### Feature-gated lints
Lints belonging to a feature should only be usable if the feature is enabled in the
@@ -722,6 +722,7 @@ meaning that rustc exclusively exposes to users as "future incompatible".
meaning in an upcoming *edition*. These are often called "edition lints" and can be
typically seen in the various "edition compatibility" lint groups (e.g., `rust_2021_compatibility`)
that are used to lint against code that will break if the user updates the crate's edition.
+See [migration lints](guides/editions.md#migration-lints) for more details.
A future-incompatible lint should be declared with the `@future_incompatible`
additional "field":
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
index 603c9ed65..54dd841ad 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
@@ -4,9 +4,8 @@ This page documents some of the machinery around lint registration and how we
run lints in the compiler.
The [`LintStore`] is the central piece of infrastructure, around which
-everything rotates. It's not available during the early parts of compilation
-(i.e., before TyCtxt) in most code, as we need to fill it in with all of the
-lints, which can only happen after plugin registration.
+everything rotates. The `LintStore` is held as part of the [`Session`], and it
+gets populated with the list of lints shortly after the `Session` is created.
## Lints vs. lint passes
@@ -39,16 +38,15 @@ lints are emitted as part of other work (e.g., type checking, etc.).
### High-level overview
-In [`rustc_interface::register_plugins`],
+In [`rustc_interface::run_compiler`],
the [`LintStore`] is created,
and all lints are registered.
-There are four 'sources' of lints:
+There are three 'sources' of lints:
* internal lints: lints only used by the rustc codebase
* builtin lints: lints built into the compiler and not provided by some outside
source
-* plugin lints: lints created by plugins through the plugin system.
* `rustc_interface::Config`[`register_lints`]: lints passed into the compiler
during construction
@@ -56,8 +54,7 @@ Lints are registered via the [`LintStore::register_lint`] function. This should
happen just once for any lint, or an ICE will occur.
Once the registration is complete, we "freeze" the lint store by placing it in
-an `Lrc`. Later in the driver, it's passed into the `GlobalCtxt` constructor
-where it lives in an immutable form from then on.
+an `Lrc`.
Lint passes are registered separately into one of the categories
(pre-expansion, early, late, late module). Passes are registered as a closure
@@ -68,8 +65,8 @@ they can keep track of state internally.
#### Internal lints
-These are lints used just by the compiler or plugins like `clippy`. They can be
-found in `rustc_lint::internal`.
+These are lints used just by the compiler or drivers like `clippy`. They can be
+found in [`rustc_lint::internal`].
An example of such a lint is the check that lint passes are implemented using
the `declare_lint_pass!` macro and not by hand. This is accomplished with the
@@ -92,18 +89,6 @@ the [`rustc_lint::register_builtins`] function.
Just like with internal lints,
this happens inside of [`rustc_lint::new_lint_store`].
-#### Plugin lints
-
-This is one of the primary use cases remaining for plugins/drivers. Plugins are
-given access to the mutable `LintStore` during registration (which happens
-inside of [`rustc_interface::register_plugins`]) and they can call any
-functions they need on the `LintStore`, just like rustc code.
-
-Plugins are intended to declare lints with the `plugin` field set to true
-(e.g., by way of the [`declare_tool_lint!`] macro), but this is purely for
-diagnostics and help text; otherwise plugin lints are mostly just as first
-class as rustc builtin lints.
-
#### Driver lints
These are the lints provided by drivers via the `rustc_interface::Config`
@@ -127,7 +112,6 @@ approach, it is beneficial to do so for performance reasons.
[`LintStore`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html
[`LintStore::register_lint`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html#method.register_lints
-[`rustc_interface::register_plugins`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/passes/fn.register_plugins.html
[`rustc_lint::register_builtins`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/fn.register_builtins.html
[`rustc_lint::register_internals`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/fn.register_internals.html
[`rustc_lint::new_lint_store`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/fn.new_lint_store.html
@@ -135,3 +119,6 @@ approach, it is beneficial to do so for performance reasons.
[`declare_tool_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/macro.declare_tool_lint.html
[`register_lints`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Config.html#structfield.register_lints
[`&rustc_lint_defs::Lint`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/struct.Lint.html
+[`Session`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html
+[`rustc_interface::run_compiler`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/index.html#reexport.run_compiler
+[`rustc_lint::internal`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/internal/index.html
diff --git a/src/doc/rustc-dev-guide/src/feature-gates.md b/src/doc/rustc-dev-guide/src/feature-gates.md
index 788f93d66..24ce9bb71 100644
--- a/src/doc/rustc-dev-guide/src/feature-gates.md
+++ b/src/doc/rustc-dev-guide/src/feature-gates.md
@@ -25,7 +25,7 @@ To remove a feature gate, follow these steps:
```rust,ignore
/// description of feature
- (unstable, $feature_name, "$version", Some($tracking_issue_number), $edition)
+ (unstable, $feature_name, "$version", Some($tracking_issue_number))
```
2. Add a modified version of the feature gate declaration that you just
@@ -33,7 +33,7 @@ To remove a feature gate, follow these steps:
```rust,ignore
/// description of feature
- (removed, $old_feature_name, "$version", Some($tracking_issue_number), $edition,
+ (removed, $old_feature_name, "$version", Some($tracking_issue_number),
Some("$why_it_was_removed"))
```
@@ -50,7 +50,7 @@ to follow when [removing a feature gate][removing]):
```rust,ignore
/// description of feature
- (unstable, $old_feature_name, "$version", Some($tracking_issue_number), $edition)
+ (unstable, $old_feature_name, "$version", Some($tracking_issue_number))
```
2. Add a modified version of the old feature gate declaration that you just
@@ -59,7 +59,7 @@ to follow when [removing a feature gate][removing]):
```rust,ignore
/// description of feature
/// Renamed to `$new_feature_name`
- (removed, $old_feature_name, "$version", Some($tracking_issue_number), $edition,
+ (removed, $old_feature_name, "$version", Some($tracking_issue_number),
Some("renamed to `$new_feature_name`"))
```
@@ -69,7 +69,7 @@ to follow when [removing a feature gate][removing]):
```rust,ignore
/// description of feature
- (unstable, $new_feature_name, "$version", Some($tracking_issue_number), $edition)
+ (unstable, $new_feature_name, "$version", Some($tracking_issue_number))
```
diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md
index a12cb068c..ef54a3009 100644
--- a/src/doc/rustc-dev-guide/src/getting-started.md
+++ b/src/doc/rustc-dev-guide/src/getting-started.md
@@ -47,12 +47,11 @@ guide :)
### Experts
-Not all `t-compiler` members are experts on all parts of `rustc`; it's a pretty
-large project. To find out who has expertise on different parts of the
-compiler, [consult this "experts map"][map].
-
-It's not perfectly complete, though, so please also feel free to ask questions
-even if you can't figure out who to ping.
+Not all `t-compiler` members are experts on all parts of `rustc`; it's a
+pretty large project. To find out who could have some expertise on
+different parts of the compiler, [consult traigebot assign groups][map].
+The sections that start with `[assign*` in `triagebot.toml` file.
+But also, feel free to ask questions even if you can't figure out who to ping.
Another way to find experts for a given part of the compiler is to see who has made recent commits.
For example, to find people who have recently worked on name resolution since the 1.68.2 release,
@@ -60,7 +59,7 @@ you could run `git shortlog -n 1.68.2.. compiler/rustc_resolve/`. Ignore any com
"Rollup merge" or commits by `@bors` (see [CI contribution procedures](./contributing.md#ci) for
more information about these commits).
-[map]: https://github.com/rust-lang/compiler-team/blob/master/content/experts/map.toml
+[map]: https://github.com/rust-lang/rust/blob/master/triagebot.toml
### Etiquette
@@ -165,7 +164,6 @@ incredibly helpful:
[users]: https://users.rust-lang.org/
[so]: http://stackoverflow.com/questions/tagged/rust
[community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library
-
[iceb]: ./notification-groups/cleanup-crew.md
[wd]: ./contributing.md#writing-documentation
[wg]: https://rust-lang.github.io/compiler-team/working-groups/
diff --git a/src/doc/rustc-dev-guide/src/guides/editions.md b/src/doc/rustc-dev-guide/src/guides/editions.md
new file mode 100644
index 000000000..336e391df
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/guides/editions.md
@@ -0,0 +1,336 @@
+# Editions
+
+<!-- toc -->
+
+This chapter gives an overview of how Edition support works in rustc.
+This assumes that you are familiar with what Editions are (see the [Edition Guide]).
+
+[Edition Guide]: https://doc.rust-lang.org/edition-guide/
+
+## Edition definition
+
+The `--edition` CLI flag specifies the edition to use for a crate.
+This can be accessed from [`Session::edition`].
+There are convenience functions like [`Session::at_least_rust_2021`] for checking the crate's
+edition, though you should be careful about whether you check the global session or the span, see
+[Edition hygiene] below.
+
+As an alternative to the `at_least_rust_20xx` convenience methods, the [`Edition`] type also
+supports comparisons for doing range checks, such as `span.edition() >= Edition::Edition2021`.
+
+[`Session::edition`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html#method.edition
+[`Session::at_least_rust_2021`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html#method.at_least_rust_2021
+[`Edition`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/edition/enum.Edition.html
+
+### Adding a new edition
+
+Adding a new edition mainly involves adding a variant to the [`Edition`] enum and then fixing
+everything that is broken. See [#94461](https://github.com/rust-lang/rust/pull/94461) for an
+example.
+
+### Features and Edition stability
+
+The [`Edition`] enum defines whether or not an edition is stable.
+If it is not stable, then the `-Zunstable-options` CLI option must be passed to enable it.
+
+When adding a new feature, there are two options you can choose for how to handle stability with a
+future edition:
+
+- Just check the edition of the span like `span.at_least_rust_20xx()` (see [Edition hygiene]) or the
+ [`Session::edition`]. This will implicitly depend on the stability of the edition itself to
+ indicate that your feature is available.
+- Place your new behavior behind a [feature gate].
+
+It may be sufficient to only check the current edition for relatively simple changes.
+However, for larger language changes, you should consider creating a feature gate.
+There are several benefits to using a feature gate:
+
+- A feature gate makes it easier to work on and experiment with a new feature.
+- It makes the intent clear when the `#![feature(…)]` attribute is used that your new feature is
+ being enabled.
+- It makes testing of editions easier so that features that are not yet complete do not interfere
+ with testing of edition-specific features that are complete and ready.
+- It decouples the feature from an edition, which makes it easier for the team to make a deliberate
+ decision of whether or not a feature should be added to the next edition when the feature is
+ ready.
+
+When a feature is complete and ready, the feature gate can be removed (and the code should just
+check the span or `Session` edition to determine if it is enabled).
+
+There are a few different options for doing feature checks:
+
+- For highly experimental features, that may or may not be involved in an edition, they can
+ implement regular feature gates like `tcx.features().my_feature`, and ignore editions for the time
+ being.
+
+- For experimental features that *might* be involved in an edition, they should implement gates with
+ `tcx.features().my_feature && span.at_least_rust_20xx()`.
+ This requires the user to still specify `#![feature(my_feature)]`, to avoid disrupting testing of
+ other edition features which are ready and have been accepted within the edition.
+
+- For experimental features that have graduated to definitely be part of an edition,
+ they should implement gates with `tcx.features().my_feature || span.at_least_rust_20xx()`,
+ or just remove the feature check altogether and just check `span.at_least_rust_20xx()`.
+
+If you need to do the feature gating in multiple places, consider placing the check in a single
+function so that there will only be a single place to update. For example:
+
+```rust,ignore
+// An example from Edition 2021 disjoint closure captures.
+
+fn enable_precise_capture(tcx: TyCtxt<'_>, span: Span) -> bool {
+ tcx.features().capture_disjoint_fields || span.rust_2021()
+}
+```
+
+See [Lints and stability](#lints-and-stability) below for more information about how lints handle
+stability.
+
+[feature gate]: ../feature-gates.md
+
+## Edition parsing
+
+For the most part, the lexer is edition-agnostic.
+Within [`StringReader`], tokens can be modified based on edition-specific behavior.
+For example, C-String literals like `c"foo"` are split into multiple tokens in editions before 2021.
+This is also where things like reserved prefixes are handled for the 2021 edition.
+
+Edition-specific parsing is relatively rare. One example is `async fn` which checks the span of the
+token to determine if it is the 2015 edition, and emits an error in that case.
+This can only be done if the syntax was already invalid.
+
+If you need to do edition checking in the parser, you will normally want to look at the edition of
+the token, see [Edition hygiene].
+In some rare cases you may instead need to check the global edition from [`ParseSess::edition`].
+
+Most edition-specific parsing behavior is handled with [migration lints] instead of in the parser.
+This is appropriate when there is a *change* in syntax (as opposed to new syntax).
+This allows the old syntax to continue to work on previous editions.
+The lint then checks for the change in behavior.
+On older editions, the lint pass should emit the migration lint to help with migrating to new
+editions.
+On newer editions, your code should emit a hard error with `emit_err` instead.
+For example, the deprecated `start...end` pattern syntax emits the
+[`ellipsis_inclusive_range_patterns`] lint on editions before 2021, and in 2021 is an hard error via
+the `emit_err` method.
+
+[`StringReader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html
+[`ParseSess::edition`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html#structfield.edition
+[`ellipsis_inclusive_range_patterns`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/warn-by-default.html#ellipsis-inclusive-range-patterns
+
+### Keywords
+
+New keywords can be introduced across an edition boundary.
+This is implemented by functions like [`Symbol::is_used_keyword_conditional`], which rely on the
+ordering of how the keywords are defined.
+
+When new keywords are introduced, the [`keyword_idents`] lint should be updated so that automatic
+migrations can transition code that might be using the keyword as an identifier (see
+[`KeywordIdents`]).
+An alternative to consider is to implement the keyword as a weak keyword if the position it is used
+is sufficient to distinguish it.
+
+An additional option to consider is the `k#` prefix which was introduced in [RFC 3101].
+This allows the use of a keyword in editions *before* the edition where the keyword is introduced.
+This is currently not implemented.
+
+[`Symbol::is_used_keyword_conditional`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Symbol.html#method.is_used_keyword_conditional
+[`keyword_idents`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/allowed-by-default.html#keyword-idents
+[`KeywordIdents`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/builtin/struct.KeywordIdents.html
+[RFC 3101]: https://rust-lang.github.io/rfcs/3101-reserved_prefixes.html
+
+### Edition hygiene
+[edition hygiene]: #edition-hygiene
+
+Spans are marked with the edition of the crate that the span came from.
+See [Macro hygiene] in the Edition Guide for a user-centric description of what this means.
+
+You should normally use the edition from the token span instead of looking at the global `Session`
+edition.
+For example, use `span.edition().at_least_rust_2021()` instead of `sess.at_least_rust_2021()`.
+This helps ensure that macros behave correctly when used across crates.
+
+[Macro hygiene]: https://doc.rust-lang.org/nightly/edition-guide/editions/advanced-migrations.html#macro-hygiene
+
+## Lints
+
+Lints support a few different options for interacting with editions.
+Lints can be *future incompatible edition migration lints*, which are used to support
+[migrations][migration lints] to newer editions.
+Alternatively, lints can be [edition-specific](#edition-specific-lints), where they change their
+default level starting in a specific edition.
+
+### Migration lints
+[migration lints]: #migration-lints
+[migration lint]: #migration-lints
+
+*Migration lints* are used to migrate projects from one edition to the next.
+They are implemented with a `MachineApplicable` [suggestion](../diagnostics.md#suggestions) which
+will rewrite code so that it will **successfully compile in both the previous and the next
+edition**.
+For example, the [`keyword_idents`] lint will take identifiers that conflict with a new keyword to
+use the raw identifier syntax to avoid the conflict (for example changing `async` to `r#async`).
+
+Migration lints must be declared with the [`FutureIncompatibilityReason::EditionError`] or
+[`FutureIncompatibilityReason::EditionSemanticsChange`] [future-incompatible
+option](../diagnostics.md#future-incompatible-lints) in the lint declaration:
+
+```rust,ignore
+declare_lint! {
+ pub KEYWORD_IDENTS,
+ Allow,
+ "detects edition keywords being used as an identifier",
+ @future_incompatible = FutureIncompatibleInfo {
+ reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018),
+ reference: "issue #49716 <https://github.com/rust-lang/rust/issues/49716>",
+ };
+}
+```
+
+When declared like this, the lint is automatically added to the appropriate
+`rust-20xx-compatibility` lint group.
+When a user runs `cargo fix --edition`, cargo will pass the `--force-warn rust-20xx-compatibility`
+flag to force all of these lints to appear during the edition migration.
+Cargo also passes `--cap-lints=allow` so that no other lints interfere with the edition migration.
+
+Migration lints can be either `Allow` or `Warn` by default.
+If it is `Allow`, users usually won't see this warning unless they are doing an edition migration
+manually or there is a problem during the migration.
+Most migration lints are `Allow`.
+
+If it is `Warn` by default, users on all editions will see this warning.
+Only use `Warn` if you think it is important for everyone to be aware of the change, and to
+encourage people to update their code on all editions.
+Beware that new warn-by-default lint that hit many projects can be very disruptive and frustrating
+for users.
+You may consider switching an `Allow` to `Warn` several years after the edition stabilizes.
+This will only show up for the relatively small number of stragglers who have not updated to the new
+edition.
+
+[`keyword_idents`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/allowed-by-default.html#keyword-idents
+[`FutureIncompatibilityReason::EditionError`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/enum.FutureIncompatibilityReason.html#variant.EditionError
+[`FutureIncompatibilityReason::EditionSemanticsChange`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/enum.FutureIncompatibilityReason.html#variant.EditionSemanticsChange
+
+### Edition-specific lints
+
+Lints can be marked so that they have a different level starting in a specific edition.
+In the lint declaration, use the `@edition` marker:
+
+```rust,ignore
+declare_lint! {
+ pub SOME_LINT_NAME,
+ Allow,
+ "my lint description",
+ @edition Edition2024 => Warn;
+}
+```
+
+Here, `SOME_LINT_NAME` defaults to `Allow` on all editions before 2024, and then becomes `Warn`
+afterwards.
+
+This should generally be used sparingly, as there are other options:
+
+- Small impact stylistic changes unrelated to an edition can just make the lint `Warn` on all
+ editions. If you want people to adopt a different way to write things, then go ahead and commit to
+ having it show up for all projects.
+
+ Beware that if a new warn-by-default lint hits many projects, it can be very disruptive and
+ frustrating for users.
+
+- Change the new style to be a hard error in the new edition, and use a [migration lint] to
+ automatically convert projects to the new style. For example,
+ [`ellipsis_inclusive_range_patterns`] is a hard error in 2021, and warns in all previous editions.
+
+ Beware that these cannot be added after the edition stabilizes.
+
+- Migration lints can also change over time.
+ For example, the migration lint can start out as `Allow` by default.
+ For people performing the migration, they will automatically get updated to the new code.
+ Then, after some years, the lint can be made to `Warn` in previous editions.
+
+ For example [`anonymous_parameters`] was a 2018 Edition migration lint (and a hard-error in 2018)
+ that was `Allow` by default in previous editions.
+ Then, three years later, it was changed to `Warn` for all previous editions, so that all users got
+ a warning that the style was being phased out.
+ If this was a warning from the start, it would have impacted many projects and be very disruptive.
+ By making it part of the edition, most users eventually updated to the new edition and were
+ handled by the migration.
+ Switching to `Warn` only impacted a few stragglers who did not update.
+
+[`ellipsis_inclusive_range_patterns`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/warn-by-default.html#ellipsis-inclusive-range-patterns
+[`anonymous_parameters`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/warn-by-default.html#anonymous-parameters
+
+### Lints and stability
+
+Lints can be marked as being unstable, which can be helpful when developing a new edition feature,
+and you want to test out a migration lint.
+The feature gate can be specified in the lint's declaration like this:
+
+```rust,ignore
+declare_lint! {
+ pub SOME_LINT_NAME,
+ Allow,
+ "my cool lint",
+ @feature_gate = sym::my_feature_name;
+}
+```
+
+Then, the lint will only fire if the user has the appropriate `#![feature(my_feature_name)]`.
+Just beware that when it comes time to do crater runs testing the migration that the feature gate
+will need to be removed.
+
+Alternatively, you can implement an allow-by-default [migration lint] for an upcoming unstable
+edition without a feature gate.
+Although users may technically be able to enable the lint before the edition is stabilized, most
+will not notice the new lint exists, and it should not disrupt anything or cause any breakage.
+
+### Idiom lints
+
+In the 2018 edition, there was a concept of "idiom lints" under the `rust-2018-idioms` lint group.
+The concept was to have new idiomatic styles under a different lint group separate from the forced
+migrations under the `rust-2018-compatibility` lint group, giving some flexibility as to how people
+opt-in to certain edition changes.
+
+Overall this approach did not seem to work very well,
+and it is unlikely that we will use the idiom groups in the future.
+
+## Standard library changes
+
+### Preludes
+
+Each edition comes with a specific prelude of the standard library.
+These are implemented as regular modules in [`core::prelude`] and [`std::prelude`].
+New items can be added to the prelude, just beware that this can conflict with user's pre-existing
+code.
+Usually a [migration lint] should be used to migrate existing code to avoid the conflict.
+For example, [`rust_2021_prelude_collisions`] is used to handle the collisions with the new traits
+in 2021.
+
+[`core::prelude`]: https://doc.rust-lang.org/core/prelude/index.html
+[`std::prelude`]: https://doc.rust-lang.org/std/prelude/index.html
+[`rust_2021_prelude_collisions`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/allowed-by-default.html#rust-2021-prelude-collisions
+
+### Customized language behavior
+
+Usually it is not possible to make breaking changes to the standard library.
+In some rare cases, the teams may decide that the behavior change is important enough to break this
+rule.
+The downside is that this requires special handling in the compiler to be able to distinguish when
+the old and new signatures or behaviors should be used.
+
+One example is the change in method resolution for [`into_iter()` of arrays][into-iter].
+This was implemented with the `#[rustc_skip_array_during_method_dispatch]` attribute on the
+`IntoIterator` trait which then tells the compiler to consider an alternate trait resolution choice
+based on the edition.
+
+Another example is the [`panic!` macro changes][panic-macro].
+This required defining multiple panic macros, and having the built-in panic macro implementation
+determine the appropriate way to expand it.
+This also included the [`non_fmt_panics`] [migration lint] to adjust old code to the new form, which
+required the `rustc_diagnostic_item` attribute to detect the usage of the panic macro.
+
+In general it is recommended to avoid these special cases except for very high value situations.
+
+[into-iter]: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html
+[panic-macro]: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html
+[`non_fmt_panics`]: https://doc.rust-lang.org/nightly/rustc/lints/listing/warn-by-default.html#non-fmt-panics
diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md
index 427589dab..0140c09bb 100644
--- a/src/doc/rustc-dev-guide/src/implementing_new_features.md
+++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md
@@ -128,10 +128,10 @@ a new unstable feature:
```rust ignore
/// description of feature
- (unstable, $feature_name, "CURRENT_RUSTC_VERSION", Some($tracking_issue_number), $edition)
+ (unstable, $feature_name, "CURRENT_RUSTC_VERSION", Some($tracking_issue_number))
```
- where `$edition` has the type `Option<Edition>`, and is typically just `None`. If you haven't yet
+ If you haven't yet
opened a tracking issue (e.g. because you want initial feedback on whether the feature is likely
to be accepted), you can temporarily use `None` - but make sure to update it before the PR is
merged!
diff --git a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
index fd215e3e9..a21254946 100644
--- a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
+++ b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
@@ -273,20 +273,22 @@ since it will not be called), and adds a new `FunctionCoverage`, with
## Testing LLVM Coverage
-[(See also the compiletest documentation for the `tests/coverage-map` and
-`tests/run-coverage` test suites.)](./tests/compiletest.md#coverage-tests)
+[(See also the compiletest documentation for the `tests/coverage`
+test suite.)](./tests/compiletest.md#coverage-tests)
Coverage instrumentation in the MIR is validated by a `mir-opt` test:
[`tests/mir-opt/instrument_coverage.rs`].
-Coverage instrumentation in LLVM IR is validated by the [`tests/coverage-map`]
-test suite. These tests compile a test program to LLVM IR assembly, and then
+Coverage instrumentation in LLVM IR is validated by the [`tests/coverage`]
+test suite in `coverage-map` mode.
+These tests compile a test program to LLVM IR assembly, and then
use the [`src/tools/coverage-dump`] tool to extract and pretty-print the
coverage mappings that would be embedded in the final binary.
End-to-end testing of coverage instrumentation and coverage reporting is
-performed by the [`tests/run-coverage`] and [`tests/run-coverage-rustdoc`]
-test suites. These tests compile and run a test program with coverage
+performed by the [`tests/coverage`] test suite in `coverage-run` mode,
+and by the [`tests/coverage-run-rustdoc`] test suite.
+These tests compile and run a test program with coverage
instrumentation, then use LLVM tools to convert the coverage data into a
human-readable coverage report.
@@ -296,19 +298,19 @@ expected LLVM IR instructions and structured data for a coverage-enabled
program, including various checks for Coverage Map-related metadata and the LLVM
intrinsic calls to increment the runtime counters.
-Expected results for the `coverage-map`, `run-coverage`, `run-coverage-rustdoc`,
+Expected results for the `coverage`, `coverage-run-rustdoc`,
and `mir-opt` tests can be refreshed by running:
```shell
-./x test tests/*coverage* --bless
+./x test coverage --bless
+./x test coverage-run-rustdoc --bless
./x test tests/mir-opt --bless
```
[`tests/mir-opt/instrument_coverage.rs`]: https://github.com/rust-lang/rust/blob/master/tests/mir-opt/instrument_coverage.rs
-[`tests/coverage-map`]: https://github.com/rust-lang/rust/tree/master/tests/coverage-map
+[`tests/coverage`]: https://github.com/rust-lang/rust/tree/master/tests/coverage
[`src/tools/coverage-dump`]: https://github.com/rust-lang/rust/tree/master/src/tools/coverage-dump
-[`tests/run-coverage`]: https://github.com/rust-lang/rust/tree/master/tests/run-coverage
-[`tests/run-coverage-rustdoc`]: https://github.com/rust-lang/rust/tree/master/tests/run-coverage-rustdoc
+[`tests/coverage-run-rustdoc`]: https://github.com/rust-lang/rust/tree/master/tests/coverage-run-rustdoc
[`coverage-llvmir`]: https://github.com/rust-lang/rust/tree/master/tests/run-make/coverage-llvmir
## Implementation Details of the `InstrumentCoverage` MIR Pass
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/arm.md b/src/doc/rustc-dev-guide/src/notification-groups/arm.md
index 4514f8ef3..3abc32c68 100644
--- a/src/doc/rustc-dev-guide/src/notification-groups/arm.md
+++ b/src/doc/rustc-dev-guide/src/notification-groups/arm.md
@@ -1,6 +1,7 @@
# ARM notification group
-**Github Label:** [O-ARM]
+**Github Label:** [O-ARM] <br>
+**Ping command:** `@rustbot ping arm`
[O-ARM]: https://github.com/rust-lang/rust/labels/O-ARM
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md b/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md
index 707334304..9cf4e512c 100644
--- a/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md
+++ b/src/doc/rustc-dev-guide/src/notification-groups/cleanup-crew.md
@@ -1,6 +1,7 @@
# Cleanup Crew
-**Github Label:** [ICEBreaker-Cleanup-Crew]
+**Github Label:** [ICEBreaker-Cleanup-Crew] <br>
+**Ping command:** `@rustbot ping cleanup-crew`
[ICEBreaker-Cleanup-Crew]: https://github.com/rust-lang/rust/labels/ICEBreaker-Cleanup-Crew
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/llvm.md b/src/doc/rustc-dev-guide/src/notification-groups/llvm.md
index 69edd8b54..2eff63713 100644
--- a/src/doc/rustc-dev-guide/src/notification-groups/llvm.md
+++ b/src/doc/rustc-dev-guide/src/notification-groups/llvm.md
@@ -1,6 +1,7 @@
# LLVM Notification group
-**Github Label:** [A-LLVM]
+**Github Label:** [A-LLVM] <br>
+**Ping command:** `@rustbot ping llvm`
[A-LLVM]: https://github.com/rust-lang/rust/labels/A-LLVM
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/risc-v.md b/src/doc/rustc-dev-guide/src/notification-groups/risc-v.md
index 15ce1cfc6..1b31297b6 100644
--- a/src/doc/rustc-dev-guide/src/notification-groups/risc-v.md
+++ b/src/doc/rustc-dev-guide/src/notification-groups/risc-v.md
@@ -1,6 +1,7 @@
# RISC-V notification group
-**Github Label:** [O-riscv]
+**Github Label:** [O-riscv] <br>
+**Ping command:** `@rustbot ping risc-v`
[O-riscv]: https://github.com/rust-lang/rust/labels/O-riscv
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/windows.md b/src/doc/rustc-dev-guide/src/notification-groups/windows.md
index 0483babd8..e615a2cbd 100644
--- a/src/doc/rustc-dev-guide/src/notification-groups/windows.md
+++ b/src/doc/rustc-dev-guide/src/notification-groups/windows.md
@@ -1,6 +1,7 @@
# Windows notification group
-**Github Label:** [O-Windows]
+**Github Label:** [O-Windows] <br>
+**Ping command:** `@rustbot ping windows`
[O-Windows]: https://github.com/rust-lang/rust/labels/O-Windows
diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md
index 5cacb3013..7b6ed435d 100644
--- a/src/doc/rustc-dev-guide/src/tests/compiletest.md
+++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md
@@ -67,11 +67,8 @@ The following test suites are available, with links for more information:
- `run-make-fulldeps` — `run-make` tests which require a linkable build of `rustc`,
or the rust demangler
- [`run-pass-valgrind`](#valgrind-tests) — tests run with Valgrind
-- [`coverage-map`](#coverage-tests) - tests for coverage maps produced by
- coverage instrumentation
-- [`run-coverage`](#coverage-tests) - tests that run an instrumented program
- and check its coverage report
-- [`run-coverage-rustdoc`](#coverage-tests) - coverage tests that also run
+- [`coverage`](#coverage-tests) - tests for coverage instrumentation
+- [`coverage-run-rustdoc`](#coverage-tests) - coverage tests that also run
instrumented doctests
- [Rustdoc tests](../rustdoc.md#tests):
- `rustdoc` — tests for rustdoc, making sure that the generated files
@@ -402,7 +399,28 @@ These may be removed in the future.
### Coverage tests
-The tests in [`tests/coverage-map`] test the mappings between source code
+The tests in [`tests/coverage`] are shared by multiple test modes that test
+coverage instrumentation in different ways.
+Running the `coverage` test suite will automatically run each test in all of
+the different coverage modes.
+
+Each mode also has an alias to run the coverage tests in just that mode:
+
+```bash
+./x test coverage # runs all of tests/coverage in all coverage modes
+./x test tests/coverage # same as above
+
+./x test tests/coverage/if.rs # runs the specified test in all coverage modes
+
+./x test coverage-map # runs all of tests/coverage in "coverage-map" mode only
+./x test coverage-run # runs all of tests/coverage in "coverage-run" mode only
+
+./x test coverage-map -- tests/coverage/if.rs # runs the specified test in "coverage-map" mode only
+```
+
+---
+
+In `coverage-map` mode, these tests verify the mappings between source code
regions and coverage counters that are emitted by LLVM.
They compile the test with `--emit=llvm-ir`,
then use a custom tool ([`src/tools/coverage-dump`])
@@ -416,18 +434,18 @@ coverage reports.
As a rule of thumb, any PR that doesn't change coverage-specific
code should **feel free to re-bless** the `coverage-map` tests as necessary,
-without worrying about the actual changes, as long as the `run-coverage` tests
+without worrying about the actual changes, as long as the `coverage-run` tests
still pass.
---
-The tests in [`tests/run-coverage`] perform an end-to-end test of coverage reporting.
+In `coverage-run` mode, these tests perform an end-to-end test of coverage reporting.
They compile a test program with coverage instrumentation, run that program to
produce raw coverage data, and then use LLVM tools to process that data into a
human-readable code coverage report.
Instrumented binaries need to be linked against the LLVM profiler runtime,
-so `run-coverage` tests are **automatically skipped**
+so `coverage-run` tests are **automatically skipped**
unless the profiler runtime is enabled in `config.toml`:
```toml
@@ -439,14 +457,15 @@ profiler = true
This also means that they typically don't run in PR CI jobs,
though they do run as part of the full set of CI jobs used for merging.
-The tests in [`tests/run-coverage-rustdoc`] also run instrumented doctests and
+---
+
+The tests in [`tests/coverage-run-rustdoc`] also run instrumented doctests and
include them in the coverage report. This avoids having to build rustdoc when
-only running the main `run-coverage` suite.
+only running the main `coverage` suite.
-[`tests/coverage-map`]: https://github.com/rust-lang/rust/tree/master/tests/coverage-map
+[`tests/coverage`]: https://github.com/rust-lang/rust/tree/master/tests/coverage
[`src/tools/coverage-dump`]: https://github.com/rust-lang/rust/tree/master/src/tools/coverage-dump
-[`tests/run-coverage`]: https://github.com/rust-lang/rust/tree/master/tests/run-coverage
-[`tests/run-coverage-rustdoc`]: https://github.com/rust-lang/rust/tree/master/tests/run-coverage-rustdoc
+[`tests/coverage-run-rustdoc`]: https://github.com/rust-lang/rust/tree/master/tests/coverage-run-rustdoc
## Building auxiliary crates
diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md
index 71fb82b68..7c68dd03f 100644
--- a/src/doc/rustc-dev-guide/src/tests/running.md
+++ b/src/doc/rustc-dev-guide/src/tests/running.md
@@ -320,3 +320,36 @@ communicate with the server to coordinate running tests (see
[remote-test-server]: https://github.com/rust-lang/rust/tree/master/src/tools/remote-test-server
[src/bootstrap/test.rs]: https://github.com/rust-lang/rust/tree/master/src/bootstrap/test.rs
+## Running rustc_codegen_gcc tests
+
+First thing to know is that it only supports linux x86_64 at the moment. We will
+extend its support later on.
+
+You need to update `codegen-backends` value in your `config.toml` file in the
+`[rust]` section and add "gcc" in the array:
+
+```toml
+codegen-backends = ["llvm", "gcc"]
+```
+
+Then you need to install libgccjit 12. For example with `apt`:
+
+```bash
+$ apt install libgccjit-12-dev
+```
+
+Now you can run the following command:
+
+```bash
+$ ./x.py test compiler/rustc_codegen_gcc/
+```
+
+If it cannot find the `.so` library (if you installed it with `apt` for example), you
+need to pass the library file path with `LIBRARY_PATH`:
+
+```bash
+$ LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/ ./x.py test compiler/rustc_codegen_gcc/
+```
+
+If you encounter bugs or problems, don't hesitate to open issues on
+[rustc_codegen_gcc repository](github.com/rust-lang/rustc_codegen_gcc/).
diff --git a/src/doc/rustc-dev-guide/src/traits/canonicalization.md b/src/doc/rustc-dev-guide/src/traits/canonicalization.md
new file mode 100644
index 000000000..4c7575f62
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/traits/canonicalization.md
@@ -0,0 +1,260 @@
+# Canonicalization
+
+> **NOTE**: FIXME: The content of this chapter has some overlap with
+> [Next-gen trait solving Canonicalization chapter](../solve/canonicalization.html).
+> It is suggested to reorganize these contents in the future.
+
+Canonicalization is the process of **isolating** an inference value
+from its context. It is a key part of implementing
+[canonical queries][cq], and you may wish to read the parent chapter
+to get more context.
+
+Canonicalization is really based on a very simple concept: every
+[inference variable](../type-inference.html#vars) is always in one of
+two states: either it is **unbound**, in which case we don't know yet
+what type it is, or it is **bound**, in which case we do. So to
+isolate some data-structure T that contains types/regions from its
+environment, we just walk down and find the unbound variables that
+appear in T; those variables get replaced with "canonical variables",
+starting from zero and numbered in a fixed order (left to right, for
+the most part, but really it doesn't matter as long as it is
+consistent).
+
+[cq]: ./canonical-queries.html
+
+So, for example, if we have the type `X = (?T, ?U)`, where `?T` and
+`?U` are distinct, unbound inference variables, then the canonical
+form of `X` would be `(?0, ?1)`, where `?0` and `?1` represent these
+**canonical placeholders**. Note that the type `Y = (?U, ?T)` also
+canonicalizes to `(?0, ?1)`. But the type `Z = (?T, ?T)` would
+canonicalize to `(?0, ?0)` (as would `(?U, ?U)`). In other words, the
+exact identity of the inference variables is not important – unless
+they are repeated.
+
+We use this to improve caching as well as to detect cycles and other
+things during trait resolution. Roughly speaking, the idea is that if
+two trait queries have the same canonical form, then they will get
+the same answer. That answer will be expressed in terms of the
+canonical variables (`?0`, `?1`), which we can then map back to the
+original variables (`?T`, `?U`).
+
+## Canonicalizing the query
+
+To see how it works, imagine that we are asking to solve the following
+trait query: `?A: Foo<'static, ?B>`, where `?A` and `?B` are unbound.
+This query contains two unbound variables, but it also contains the
+lifetime `'static`. The trait system generally ignores all lifetimes
+and treats them equally, so when canonicalizing, we will *also*
+replace any [free lifetime](../appendix/background.html#free-vs-bound) with a
+canonical variable (Note that `'static` is actually a _free_ lifetime
+variable here. We are not considering it in the typing context of the whole
+program but only in the context of this trait reference. Mathematically, we
+are not quantifying over the whole program, but only this obligation).
+Therefore, we get the following result:
+
+```text
+?0: Foo<'?1, ?2>
+```
+
+Sometimes we write this differently, like so:
+
+```text
+for<T,L,T> { ?0: Foo<'?1, ?2> }
+```
+
+This `for<>` gives some information about each of the canonical
+variables within. In this case, each `T` indicates a type variable,
+so `?0` and `?2` are types; the `L` indicates a lifetime variable, so
+`?1` is a lifetime. The `canonicalize` method *also* gives back a
+`CanonicalVarValues` array OV with the "original values" for each
+canonicalized variable:
+
+```text
+[?A, 'static, ?B]
+```
+
+We'll need this vector OV later, when we process the query response.
+
+## Executing the query
+
+Once we've constructed the canonical query, we can try to solve it.
+To do so, we will wind up creating a fresh inference context and
+**instantiating** the canonical query in that context. The idea is that
+we create a substitution S from the canonical form containing a fresh
+inference variable (of suitable kind) for each canonical variable.
+So, for our example query:
+
+```text
+for<T,L,T> { ?0: Foo<'?1, ?2> }
+```
+
+the substitution S might be:
+
+```text
+S = [?A, '?B, ?C]
+```
+
+We can then replace the bound canonical variables (`?0`, etc) with
+these inference variables, yielding the following fully instantiated
+query:
+
+```text
+?A: Foo<'?B, ?C>
+```
+
+Remember that substitution S though! We're going to need it later.
+
+OK, now that we have a fresh inference context and an instantiated
+query, we can go ahead and try to solve it. The trait solver itself is
+explained in more detail in [another section](./slg.html), but
+suffice to say that it will compute a [certainty value][cqqr] (`Proven` or
+`Ambiguous`) and have side-effects on the inference variables we've
+created. For example, if there were only one impl of `Foo`, like so:
+
+[cqqr]: ./canonical-queries.html#query-response
+
+```rust,ignore
+impl<'a, X> Foo<'a, X> for Vec<X>
+where X: 'a
+{ ... }
+```
+
+then we might wind up with a certainty value of `Proven`, as well as
+creating fresh inference variables `'?D` and `?E` (to represent the
+parameters on the impl) and unifying as follows:
+
+- `'?B = '?D`
+- `?A = Vec<?E>`
+- `?C = ?E`
+
+We would also accumulate the region constraint `?E: '?D`, due to the
+where clause.
+
+In order to create our final query result, we have to "lift" these
+values out of the query's inference context and into something that
+can be reapplied in our original inference context. We do that by
+**re-applying canonicalization**, but to the **query result**.
+
+## Canonicalizing the query result
+
+As discussed in [the parent section][cqqr], most trait queries wind up
+with a result that brings together a "certainty value" `certainty`, a
+result substitution `var_values`, and some region constraints. To
+create this, we wind up re-using the substitution S that we created
+when first instantiating our query. To refresh your memory, we had a query
+
+```text
+for<T,L,T> { ?0: Foo<'?1, ?2> }
+```
+
+for which we made a substutition S:
+
+```text
+S = [?A, '?B, ?C]
+```
+
+We then did some work which unified some of those variables with other things.
+If we "refresh" S with the latest results, we get:
+
+```text
+S = [Vec<?E>, '?D, ?E]
+```
+
+These are precisely the new values for the three input variables from
+our original query. Note though that they include some new variables
+(like `?E`). We can make those go away by canonicalizing again! We don't
+just canonicalize S, though, we canonicalize the whole query response QR:
+
+```text
+QR = {
+ certainty: Proven, // or whatever
+ var_values: [Vec<?E>, '?D, ?E] // this is S
+ region_constraints: [?E: '?D], // from the impl
+ value: (), // for our purposes, just (), but
+ // in some cases this might have
+ // a type or other info
+}
+```
+
+The result would be as follows:
+
+```text
+Canonical(QR) = for<T, L> {
+ certainty: Proven,
+ var_values: [Vec<?0>, '?1, ?0]
+ region_constraints: [?0: '?1],
+ value: (),
+}
+```
+
+(One subtle point: when we canonicalize the query **result**, we do not
+use any special treatment for free lifetimes. Note that both
+references to `'?D`, for example, were converted into the same
+canonical variable (`?1`). This is in contrast to the original query,
+where we canonicalized every free lifetime into a fresh canonical
+variable.)
+
+Now, this result must be reapplied in each context where needed.
+
+## Processing the canonicalized query result
+
+In the previous section we produced a canonical query result. We now have
+to apply that result in our original context. If you recall, way back in the
+beginning, we were trying to prove this query:
+
+```text
+?A: Foo<'static, ?B>
+```
+
+We canonicalized that into this:
+
+```text
+for<T,L,T> { ?0: Foo<'?1, ?2> }
+```
+
+and now we got back a canonical response:
+
+```text
+for<T, L> {
+ certainty: Proven,
+ var_values: [Vec<?0>, '?1, ?0]
+ region_constraints: [?0: '?1],
+ value: (),
+}
+```
+
+We now want to apply that response to our context. Conceptually, how
+we do that is to (a) instantiate each of the canonical variables in
+the result with a fresh inference variable, (b) unify the values in
+the result with the original values, and then (c) record the region
+constraints for later. Doing step (a) would yield a result of
+
+```text
+{
+ certainty: Proven,
+ var_values: [Vec<?C>, '?D, ?C]
+ ^^ ^^^ fresh inference variables
+ region_constraints: [?C: '?D],
+ value: (),
+}
+```
+
+Step (b) would then unify:
+
+```text
+?A with Vec<?C>
+'static with '?D
+?B with ?C
+```
+
+And finally the region constraint of `?C: 'static` would be recorded
+for later verification.
+
+(What we *actually* do is a mildly optimized variant of that: Rather
+than eagerly instantiating all of the canonical values in the result
+with variables, we instead walk the vector of values, looking for
+cases where the value is just a canonical variable. In our example,
+`values[2]` is `?C`, so that means we can deduce that `?C := ?B` and
+`'?D := 'static`. This gives us a partial set of values. Anything for
+which we do not find a value, we create an inference variable.)
+
diff --git a/src/doc/rustc-dev-guide/src/walkthrough.md b/src/doc/rustc-dev-guide/src/walkthrough.md
index 5e22f10e4..b8311b19a 100644
--- a/src/doc/rustc-dev-guide/src/walkthrough.md
+++ b/src/doc/rustc-dev-guide/src/walkthrough.md
@@ -181,7 +181,7 @@ gate is removed when the feature is stabilized.
make your changes/improvements.
When you open a PR on the [rust-lang/rust], a bot will assign your PR to a
-review. If there is a particular Rust team member you are working with, you can
+reviewer. If there is a particular Rust team member you are working with, you can
request that reviewer by leaving a comment on the thread with `r?
@reviewer-github-id` (e.g. `r? @eddyb`). If you don't know who to request,
don't request anyone; the bot will assign someone automatically based on which files you changed.