diff options
Diffstat (limited to 'src/doc/rustc-dev-guide')
30 files changed, 260 insertions, 309 deletions
diff --git a/src/doc/rustc-dev-guide/src/asm.md b/src/doc/rustc-dev-guide/src/asm.md index cd5430ffd..9b5a82f34 100644 --- a/src/doc/rustc-dev-guide/src/asm.md +++ b/src/doc/rustc-dev-guide/src/asm.md @@ -10,12 +10,13 @@ through all of the compiler layers down to LLVM codegen. Throughout the various - The template string, which is stored as an array of `InlineAsmTemplatePiece`. Each piece represents either a literal or a placeholder for an operand (just like format strings). -```rust -pub enum InlineAsmTemplatePiece { - String(String), - Placeholder { operand_idx: usize, modifier: Option<char>, span: Span }, -} -``` + + ```rust + pub enum InlineAsmTemplatePiece { + String(String), + Placeholder { operand_idx: usize, modifier: Option<char>, span: Span }, + } + ``` - The list of operands to the `asm!` (`in`, `[late]out`, `in[late]out`, `sym`, `const`). These are represented differently at each stage of lowering, but follow a common pattern: @@ -34,21 +35,22 @@ or a `fn`. - The options set at the end of the `asm!` macro. The only ones that are of particular interest to rustc are `NORETURN` which makes `asm!` return `!` instead of `()`, and `RAW` which disables format string parsing. The remaining options are mostly passed through to LLVM with little processing. -```rust -bitflags::bitflags! { - pub struct InlineAsmOptions: u16 { - const PURE = 1 << 0; - const NOMEM = 1 << 1; - const READONLY = 1 << 2; - const PRESERVES_FLAGS = 1 << 3; - const NORETURN = 1 << 4; - const NOSTACK = 1 << 5; - const ATT_SYNTAX = 1 << 6; - const RAW = 1 << 7; - const MAY_UNWIND = 1 << 8; - } -} -``` + + ```rust + bitflags::bitflags! { + pub struct InlineAsmOptions: u16 { + const PURE = 1 << 0; + const NOMEM = 1 << 1; + const READONLY = 1 << 2; + const PRESERVES_FLAGS = 1 << 3; + const NORETURN = 1 << 4; + const NOSTACK = 1 << 5; + const ATT_SYNTAX = 1 << 6; + const RAW = 1 << 7; + const MAY_UNWIND = 1 << 8; + } + } + ``` ## AST diff --git a/src/doc/rustc-dev-guide/src/backend/monomorph.md b/src/doc/rustc-dev-guide/src/backend/monomorph.md index 416151ca9..21a788203 100644 --- a/src/doc/rustc-dev-guide/src/backend/monomorph.md +++ b/src/doc/rustc-dev-guide/src/backend/monomorph.md @@ -70,7 +70,7 @@ or more modules in Crate B. | Crate A function | Behavior | | - | - | | Non-generic function | Crate A function doesn't appear in any codegen units of Crate B | -| Non-generic `#[inline]` function | Crate A function appears with in a single CGU of Crate B, and exists even after post-inlining stage| +| Non-generic `#[inline]` function | Crate A function appears within a single CGU of Crate B, and exists even after post-inlining stage| | Generic function | Regardless of inlining, all monomorphized (specialized) functions <br> from Crate A appear within a single codegen unit for Crate B. <br> The codegen unit exists even after the post inlining stage.| | Generic `#[inline]` function | - same - | diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md index 81ebbbb40..38fbb2e44 100644 --- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md +++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md @@ -2,35 +2,25 @@ <!-- toc --> -The Rust compiler uses LLVM as its primary codegen backend today, and naturally -we want to at least occasionally update this dependency! Currently we do not -have a strict policy about when to update LLVM or what it can be updated to, but -a few guidelines are applied: +<!-- date-check: Aug 2022 --> +There is no formal policy about when to update LLVM or what it can be updated to, +but a few guidelines are applied: -* We try to always support the latest released version of LLVM -* We try to support the "last few" versions of LLVM (how many is changing over - time) -* We allow moving to arbitrary commits during development. -* Strongly prefer to upstream all patches to LLVM before including them in - rustc. - -This policy may change over time (or may actually start to exist as a formal -policy!), but for now these are rough guidelines! +* We try to always support the latest released version +* We try to support the last few versions + (and the number changes over time) +* We allow moving to arbitrary commits during development +* We strongly prefer to upstream all patches to LLVM before including them in rustc ## Why update LLVM? -There are a few reasons nowadays that we want to update LLVM in one way or -another: +There are two reasons we would want to update LLVM: * A bug could have been fixed! Often we find bugs in the compiler and fix them upstream in LLVM. We'll want to pull fixes back to the compiler itself as they're merged upstream. -* A new feature may be available in LLVM that we want to use in rustc, - but we don't want to wait for a full LLVM release to test it out. - -* LLVM itself may have a new release and we'd like to update to this LLVM - release. +* LLVM itself may have a new release. Each of these reasons has a different strategy for updating LLVM, and we'll go over them in detail here. @@ -57,59 +47,67 @@ the branch we're already using. The steps for this are: src/llvm-project` typically. 10. Wait for PR to be merged -The tl;dr; is that we can cherry-pick bugfixes at any time and pull them back -into the rust-lang/llvm-project branch that we're using, and getting it into the -compiler is just updating the submodule via a PR! - -Example PRs look like: +An example PR: [#59089](https://github.com/rust-lang/rust/pull/59089) -## Feature updates - -> Note that this information is as of the time of this writing, <!-- -date-check --> October 2021. The process for updating LLVM changes with -practically all LLVM updates, so this may be out of date! - -Unlike bugfixes, updating to pick up a new feature of LLVM typically requires a -lot more work. This is where we can't reasonably cherry-pick commits backwards -so we need to do a full update. There's a lot of stuff to do here, so let's go -through each in detail. - -1. Create a new branch in the [rust-lang/llvm-project repository]. This branch - should be named `rustc/a.b-yyyy-mm-dd` where `a.b` is the current version - number of LLVM in-tree at the time of the branch and the remaining part is - today's date. Move this branch to the commit in LLVM that you'd like, which - for this is probably the current LLVM HEAD. - -2. Apply Rust-specific patches to the llvm-project repository. All features and - bugfixes are upstream, but there's often some weird build-related patches - that don't make sense to upstream which we have on our repositories. These - patches are around the latest patches in the rust-lang/llvm-project branch - that rustc is currently using. +## New LLVM Release Updates -3. Build the new LLVM in the `rust` repository. To do this you'll want to update - the `src/llvm-project` repository to your branch and the revision you've - created. It's also typically a good idea to update `.gitmodules` with the new - branch name of the LLVM submodule. Make sure you've committed changes to - `src/llvm-project` to ensure submodule updates aren't reverted. Some commands - you should execute are: +<!-- date-check: Aug 2022 --> + +Unlike bugfixes, +updating to a new release of LLVM typically requires a lot more work. +This is where we can't reasonably cherry-pick commits backwards, +so we need to do a full update. +There's a lot of stuff to do here, +so let's go through each in detail. + +1. LLVM announces that its latest release version has branched. + This will show up as a branch in the [llvm/llvm-project repository], + typically named `release/$N.x`, + where `$N` is the version of LLVM that's being released. + +1. Create a new branch in the [rust-lang/llvm-project repository] + from this `release/$N.x` branch, + and name it `rustc/a.b-yyyy-mm-dd`, + where `a.b` is the current version number of LLVM in-tree + at the time of the branch, + and the remaining part is the current date. + +2. Apply Rust-specific patches to the llvm-project repository. + All features and bugfixes are upstream, + but there's often some weird build-related patches + that don't make sense to upstream. + These patches are typically the latest patches in the + rust-lang/llvm-project branch that rustc is currently using. + +3. Build the new LLVM in the `rust` repository. + To do this, + you'll want to update the `src/llvm-project` repository to your branch, + and the revision you've created. + It's also typically a good idea to update `.gitmodules` with the new + branch name of the LLVM submodule. + Make sure you've committed changes to + `src/llvm-project` to ensure submodule updates aren't reverted. + Some commands you should execute are: * `./x.py build src/llvm` - test that LLVM still builds * `./x.py build src/tools/lld` - same for LLD * `./x.py build` - build the rest of rustc - You'll likely need to update [`llvm-wrapper/*.cpp`][`llvm-wrapper`] to compile - with updated LLVM bindings. Note that you should use `#ifdef` and such to ensure + You'll likely need to update [`llvm-wrapper/*.cpp`][`llvm-wrapper`] + to compile with updated LLVM bindings. + Note that you should use `#ifdef` and such to ensure that the bindings still compile on older LLVM versions. Note that `profile = "compiler"` and other defaults set by `./x.py setup` - download LLVM from CI instead of building it from source. You should - disable this temporarily to make sure your changes are being used, by setting + download LLVM from CI instead of building it from source. + You should disable this temporarily to make sure your changes are being used. + This is done by having the following setting in `config.toml`: + ```toml [llvm] download-ci-llvm = false ``` - in config.toml. 4. Test for regressions across other platforms. LLVM often has at least one bug for non-tier-1 architectures, so it's good to do some more testing before @@ -122,7 +120,7 @@ through each in detail. * macOS * Windows - and afterwards run some docker containers that CI also does: + Afterwards, run some docker containers that CI also does: * `./src/ci/docker/run.sh wasm32` * `./src/ci/docker/run.sh arm-android` @@ -135,16 +133,39 @@ through each in detail. and then you can send a PR to `rust-lang/rust`. You'll change at least `src/llvm-project` and will likely also change [`llvm-wrapper`] as well. -For prior art, previous LLVM updates look like -[#62474](https://github.com/rust-lang/rust/pull/62474) -[#62592](https://github.com/rust-lang/rust/pull/62592) -[#67759](https://github.com/rust-lang/rust/pull/67759) -[#73526](https://github.com/rust-lang/rust/pull/73526) -[#81451](https://github.com/rust-lang/rust/pull/81451). Note that sometimes it's -easiest to land [`llvm-wrapper`] compatibility as a PR before actually updating -`src/llvm-project`. This way while you're working through LLVM issues others -interested in trying out the new LLVM can benefit from work you've done to -update the C++ bindings. + > For prior art, here are some previous LLVM updates: + > - [LLVM 11](https://github.com/rust-lang/rust/pull/73526) + > - [LLVM 12](https://github.com/rust-lang/rust/pull/81451) + > - [LLVM 13](https://github.com/rust-lang/rust/pull/87570) + > - [LLVM 14](https://github.com/rust-lang/rust/pull/93577) + > - [LLVM 15](https://github.com/rust-lang/rust/pull/99464) + + Note that sometimes it's easiest to land [`llvm-wrapper`] compatibility as a PR + before actually updating `src/llvm-project`. + This way, + while you're working through LLVM issues, + others interested in trying out the new LLVM can benefit from work you've done + to update the C++ bindings. + +3. Over the next few months, + LLVM will continually push commits to its `release/a.b` branch. + We will often want to have those bug fixes as well. + The merge process for that is to use `git merge` itself to merge LLVM's + `release/a.b` branch with the branch created in step 2. + This is typically + done multiple times when necessary while LLVM's release branch is baking. + +4. LLVM then announces the release of version `a.b`. + +5. After LLVM's official release, + we follow the process of creating a new branch on the + rust-lang/llvm-project repository again, + this time with a new date. + It is only then that the PR to update Rust to use that version is merged. + + The commit history of `rust-lang/llvm-project` + should look much cleaner as a `git rebase` is done, + where just a few Rust-specific commits are stacked on top of stock LLVM's release branch. ### Caveats and gotchas @@ -158,35 +179,6 @@ keep in mind while going through them: * Creating branches is a privileged operation on GitHub, so you'll need someone with write access to create the branches for you most likely. -## New LLVM Release Updates - -Updating to a new release of LLVM is very similar to the "feature updates" -section above. The release process for LLVM is often months-long though and we -like to ensure compatibility ASAP. The main tweaks to the "feature updates" -section above is generally around branch naming. The sequence of events -typically looks like: - -1. LLVM announces that its latest release version has branched. This will show - up as a branch in the [llvm/llvm-project repository] typically named - `release/$N.x` where `$N` is the version of LLVM that's being released. - -2. We then follow the "feature updates" section above to create a new branch of - LLVM in our rust-lang/llvm-project repository. This follows the same naming - convention of branches as usual, except that `a.b` is the new version. This - update is eventually landed in the rust-lang/rust repository. - -3. Over the next few months, LLVM will continually push commits to its - `release/a.b` branch. Often those are bug fixes we'd like to have as well. - The merge process for that is to use `git merge` itself to merge LLVM's - `release/a.b` branch with the branch created in step 2. This is typically - done multiple times when necessary while LLVM's release branch is baking. - -4. LLVM then announces the release of version `a.b`. - -5. After LLVM's official release, we follow the "feature update" section again - to create a new branch in the rust-lang/llvm-project repository, this time - with a new date. The commit history should look much cleaner as just a few - Rust-specific commits stacked on top of stock LLVM's release branch. [rust-lang/llvm-project repository]: https://github.com/rust-lang/llvm-project [llvm/llvm-project repository]: https://github.com/llvm/llvm-project diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md index 8702f8aa9..2f5e24716 100644 --- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md +++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md @@ -53,9 +53,9 @@ Please see [the RFC][rfc 1122] for full details! The procedure for making a breaking change is as follows (each of these steps is described in more detail below): -0. Do a **crater run** to assess the impact of the change. -1. Make a **special tracking issue** dedicated to the change. -1. Do not report an error right away. Instead, **issue forwards-compatibility +1. Do a **crater run** to assess the impact of the change. +2. Make a **special tracking issue** dedicated to the change. +3. Do not report an error right away. Instead, **issue forwards-compatibility lint warnings**. - Sometimes this is not straightforward. See the text below for suggestions on different techniques we have employed in the past. @@ -65,7 +65,7 @@ described in more detail below): - Submit PRs to all known affected crates that fix the issue - or, at minimum, alert the owners of those crates to the problem and direct them to the tracking issue -1. Once the change has been in the wild for at least one cycle, we can +4. Once the change has been in the wild for at least one cycle, we can **stabilize the change**, converting those warnings into errors. Finally, for changes to `rustc_ast` that will affect plugins, the general policy 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 c5cf3166d..46d4b9c04 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 @@ -152,7 +152,9 @@ is what you need to build other Rust programs (unless you use `#![no_std]` or You will probably find that building the stage1 `std` is a bottleneck for you, but fear not, there is a (hacky) workaround... -see [the section on "recommended workflows"](./suggested.md) below. +see [the section on avoiding rebuilds for std][keep-stage]. + +[keep-stage]: ./suggested.md#faster-builds-with---keep-stage Note that this whole command just gives you a subset of the full `rustc` build. The **full** `rustc` build (what you get with `./x.py build diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 5c5e571e4..a85229c6a 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -8,8 +8,9 @@ to make your life easier. CI will automatically fail your build if it doesn't pass `tidy`, our internal tool for ensuring code quality. If you'd like, you can install a [Git hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) -that will automatically run `./x.py test tidy --bless` on each push, to ensure -your code is up to par. If you decide later that this behavior is +that will automatically run `./x.py test tidy` on each push, to ensure +your code is up to par. If the hook fails then run `./x.py test tidy --bless` +and commit the changes. If you decide later that the pre-push behavior is undesirable, you can delete the `pre-push` file in `.git/hooks`. A prebuilt git hook lives at [`src/etc/pre-push.sh`](https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh) which can be copied into your `.git/hooks` folder as `pre-push` (without the `.sh` extension!). @@ -22,7 +23,7 @@ You can also install the hook as a step of running `./x.py setup`! a file. By default, `rust-analyzer` runs the `cargo check` and `rustfmt` commands, but you can override these commands to use more adapted versions of these tools when hacking on `rustc`. For example, for Visual Studio Code, -you can write: <!-- date-check: apr 2022 --><!-- the date comment is for the edition below --> +you can write: <!-- date-check: nov 2022 --><!-- the date comment is for the edition below --> ```JSON { @@ -135,13 +136,13 @@ lets you use `cargo fmt`. [the section on vscode]: suggested.md#configuring-rust-analyzer-for-rustc [the section on rustup]: how-to-build-and-run.md?highlight=rustup#creating-a-rustup-toolchain -## Incremental builds with `--keep-stage`. +## Faster builds with `--keep-stage`. Sometimes just checking whether the compiler builds is not enough. A common example is that you need to add a `debug!` statement to inspect the value of some state or better understand the problem. In that case, you really need -a full build. By leveraging incremental, though, you can often get +a full build. By bypassing bootstrap's cache invalidation, you can often get these builds to complete very fast (e.g., around 30 seconds). The only catch is this requires a bit of fudging and may produce compilers that don't work (but that is easily detected and fixed). diff --git a/src/doc/rustc-dev-guide/src/closure.md b/src/doc/rustc-dev-guide/src/closure.md index c3906a80b..5746fd4de 100644 --- a/src/doc/rustc-dev-guide/src/closure.md +++ b/src/doc/rustc-dev-guide/src/closure.md @@ -142,11 +142,11 @@ declared in the file [`compiler/rustc_middle/src/ty/mod.rs`][ty]. [ty]:https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/index.html Before we go any further, let's discuss how we can examine the flow of control through the rustc -codebase. For closures specifically, set the `RUST_LOG` env variable as below and collect the +codebase. For closures specifically, set the `RUSTC_LOG` env variable as below and collect the output in a file: ```console -> RUST_LOG=rustc_hir_typeck::upvar rustc +stage1 -Z dump-mir=all \ +> RUSTC_LOG=rustc_hir_typeck::upvar rustc +stage1 -Z dump-mir=all \ <.rs file to compile> 2> <file where the output will be dumped> ``` diff --git a/src/doc/rustc-dev-guide/src/compiler-team.md b/src/doc/rustc-dev-guide/src/compiler-team.md index abdeac3d2..4570fd3fa 100644 --- a/src/doc/rustc-dev-guide/src/compiler-team.md +++ b/src/doc/rustc-dev-guide/src/compiler-team.md @@ -111,20 +111,22 @@ The guidelines for reviewers are as follows: [Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct -### high-five +### Reviewer rotation -Once you have r+ rights, you can also be added to the [high-five][hi5] -rotation. high-five is the bot that assigns incoming PRs to -reviewers. If you are added, you will be randomly selected to review +Once you have r+ rights, you can also be added to the [reviewer rotation]. +[triagebot] is the bot that [automatically assigns] incoming PRs to reviewers. +If you are added, you will be randomly selected to review PRs. If you find you are assigned a PR that you don't feel comfortable reviewing, you can also leave a comment like `r? @so-and-so` to assign to someone else — if you don't know who to request, just write `r? @nikomatsakis for reassignment` and @nikomatsakis will pick someone for you. -[hi5]: https://github.com/rust-highfive +[reviewer rotation]: https://github.com/rust-lang/rust/blob/36285c5de8915ecc00d91ae0baa79a87ed5858d5/triagebot.toml#L528-L577 +[triagebot]: https://github.com/rust-lang/triagebot/ +[automatically assigns]: https://github.com/rust-lang/triagebot/wiki/Assignment -Getting on the high-five list is much appreciated as it lowers the +Getting on the reviewer rotation is much appreciated as it lowers the review burden for all of us! However, if you don't have time to give people timely feedback on their PRs, it may be better that you don't get on the list. diff --git a/src/doc/rustc-dev-guide/src/constants.md b/src/doc/rustc-dev-guide/src/constants.md index 4f1027b98..a33a283f3 100644 --- a/src/doc/rustc-dev-guide/src/constants.md +++ b/src/doc/rustc-dev-guide/src/constants.md @@ -79,4 +79,4 @@ the constant doesn't use them in any way. This can cause [`ty::Const`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Const.html [`ty::ConstKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.ConstKind.html [`ty::TyKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html -[pcg-unused-substs]: https://github.com/rust-lang/project-const-generics/blob/master/design-docs/anon-const-substs.md#unused-substs
\ No newline at end of file +[pcg-unused-substs]: https://github.com/rust-lang/project-const-generics/issues/33 diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 279bc2f28..41ad1c915 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -73,7 +73,7 @@ when contributing to Rust under [the git section](./git.md). ### r? All pull requests are reviewed by another person. We have a bot, -[@rust-highfive][rust-highfive], that will automatically assign a random person +[@rustbot], that will automatically assign a random person to review your request based on which files you changed. If you want to request that a specific person reviews your pull request, you @@ -82,7 +82,7 @@ if you want to ask a review to @awesome-reviewer, add r? @awesome-reviewer -to the end of the pull request description, and [@rust-highfive][rust-highfive] will assign +to the end of the pull request description, and [@rustbot] will assign them instead of a random person. This is entirely optional. You can also assign a random reviewer from a specific team by writing `r? rust-lang/groupname`. @@ -91,8 +91,10 @@ team by adding: r? rust-lang/diagnostics -For a full list of possible `groupname` check the `groups` section at the -[rust highfive config file](https://github.com/rust-lang/highfive/blob/master/highfive/configs/rust-lang/rust.json). +For a full list of possible `groupname` check the `adhoc_groups` section at the +[triagebot.toml config file](https://github.com/rust-lang/rust/blob/master/triagebot.toml) +or the list of teams in the [rust-lang teams +database](https://github.com/rust-lang/team/tree/master/teams). ### CI @@ -133,7 +135,7 @@ Changes that are rolled up are tested and merged alongside other PRs, to speed the process up. Typically only small changes that are expected not to conflict with one another are marked as "always roll up". -[rust-highfive]: https://github.com/rust-highfive +[@rustbot]: https://github.com/rustbot [@bors]: https://github.com/bors [merge-queue]: https://bors.rust-lang.org/queue/rust @@ -189,8 +191,10 @@ differently from other crates that are directly in this repo: In contrast to `submodule` dependencies (see below for those), the `subtree` dependencies are just regular files and directories which can -be updated in tree. However, enhancements, bug fixes, etc. specific to these tools should be filed -against the tools directly in their respective upstream repositories. +be updated in tree. However, if possible, enhancements, bug fixes, etc. specific +to these tools should be filed against the tools directly in their respective +upstream repositories. The exception is that when rustc changes are required to +implement a new tool feature or test, that should happen in one collective rustc PR. #### Synchronizing a subtree diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 0d5f17b99..4dd0a2da9 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -21,7 +21,7 @@ Formatting is checked by the `tidy` script. It runs automatically when you do If you want to use format-on-save in your editor, the pinned version of `rustfmt` is built under `build/<target>/stage0/bin/rustfmt`. You'll have to -pass the <!-- date-check: April 2022 --> `--edition=2021` argument yourself when calling +pass the <!-- date-check: nov 2022 --> `--edition=2021` argument yourself when calling `rustfmt` directly. [fmt]: https://github.com/rust-dev-tools/fmt-rfcs diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md index d51e79348..e26ba5f34 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md @@ -28,8 +28,10 @@ pub struct FieldAlreadyDeclared { } ``` -`Diagnostic` can only be applied to structs. Every `Diagnostic` -has to have one attribute, `#[diag(...)]`, applied to the struct itself. +`Diagnostic` can only be applied to structs and enums. +Attributes that are placed on the type for structs are placed on each +variants for enums (or vice versa). Each `Diagnostic` has to have one +attribute, `#[diag(...)]`, applied to the struct or each enum variant. If an error has an error code (e.g. "E0624"), then that can be specified using the `code` sub-attribute. Specifying a `code` isn't mandatory, but if you are @@ -198,9 +200,9 @@ following attributes: - See [translation documentation](./translation.md). - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or - `.suggestion` in Fluent). - - `code = "..."` (_Mandatory_) - - Value is a format string indicating the code to be suggested as a - replacement. + - `code = "..."`/`code("...", ...)` (_Mandatory_) + - One or multiple format strings indicating the code to be suggested as a + replacement. Multiple values signify multiple possible replacements. - `applicability = "..."` (_Optional_) - String which must be one of `machine-applicable`, `maybe-incorrect`, `has-placeholders` or `unspecified`. @@ -243,7 +245,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> { } ``` -Unlike `Diagnostic`, `Subdiagnostic` can be applied to structs or +Like `Diagnostic`, `Subdiagnostic` can be applied to structs or enums. Attributes that are placed on the type for structs are placed on each variants for enums (or vice versa). Each `Subdiagnostic` should have one attribute applied to the struct or each variant, one of: @@ -357,9 +359,9 @@ diagnostic struct. - See [translation documentation](./translation.md). - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or - `.suggestion` in Fluent). - - `code = "..."` (_Mandatory_) - - Value is a format string indicating the code to be suggested as a - replacement. + - `code = "..."`/`code("...", ...)` (_Mandatory_) + - One or multiple format strings indicating the code to be suggested as a + replacement. Multiple values signify multiple possible replacements. - `applicability = "..."` (_Optional_) - _Mutually exclusive with `#[applicability]` on a field._ - Value is the applicability of the suggestion. diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md index 33d9646f6..603c9ed65 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md @@ -14,11 +14,6 @@ There are two parts to the linting mechanism within the compiler: lints and lint passes. Unfortunately, a lot of the documentation we have refers to both of these as just "lints." -First, we have the lint declarations themselves: this is where the name and -default lint level and other metadata come from. These are normally defined by -way of the [`declare_lint!`] macro, which boils down to a static with type -[`&rustc_lint_defs::Lint`]. - First, we have the lint declarations themselves, and this is where the name and default lint level and other metadata come from. These are normally defined by way of the [`declare_lint!`] macro, diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index b4dc11a68..4e1f520ff 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -156,7 +156,7 @@ highlights, but there are a lot more details, which we will link to below. ### Code Review -When you open a PR on the `rust-lang/rust` repo, a bot called `@rust-highfive` will +When you open a PR on the `rust-lang/rust` repo, a bot called `@rustbot` will automatically assign a reviewer to the PR based on which files you changed. The reviewer is the person that will approve the PR to be tested and merged. If you want a specific reviewer (e.g. a team member you've been working with), diff --git a/src/doc/rustc-dev-guide/src/macro-expansion.md b/src/doc/rustc-dev-guide/src/macro-expansion.md index 156df8d5f..7f50f7f89 100644 --- a/src/doc/rustc-dev-guide/src/macro-expansion.md +++ b/src/doc/rustc-dev-guide/src/macro-expansion.md @@ -48,45 +48,45 @@ iteration, this represents a compile error. Here is the [algorithm][original]: [fef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/expand/struct.MacroExpander.html#method.fully_expand_fragment [original]: https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049 -0. Initialize an `queue` of unresolved macros. -1. Repeat until `queue` is empty (or we make no progress, which is an error): - 0. [Resolve](./name-resolution.md) imports in our partially built crate as - much as possible. - 1. Collect as many macro [`Invocation`s][inv] as possible from our - partially built crate (fn-like, attributes, derives) and add them to the - queue. - 2. Dequeue the first element, and attempt to resolve it. - 3. If it's resolved: - 0. Run the macro's expander function that consumes a [`TokenStream`] or - AST and produces a [`TokenStream`] or [`AstFragment`] (depending on - the macro kind). (A `TokenStream` is a collection of [`TokenTree`s][tt], - each of which are a token (punctuation, identifier, or literal) or a - delimited group (anything inside `()`/`[]`/`{}`)). - - At this point, we know everything about the macro itself and can - call `set_expn_data` to fill in its properties in the global data; - that is the hygiene data associated with `ExpnId`. (See [the - "Hygiene" section below][hybelow]). - 1. Integrate that piece of AST into the big existing partially built - AST. This is essentially where the "token-like mass" becomes a - proper set-in-stone AST with side-tables. It happens as follows: - - If the macro produces tokens (e.g. a proc macro), we parse into - an AST, which may produce parse errors. - - During expansion, we create `SyntaxContext`s (hierarchy 2). (See - [the "Hygiene" section below][hybelow]) - - These three passes happen one after another on every AST fragment - freshly expanded from a macro: - - [`NodeId`]s are assigned by [`InvocationCollector`]. This - also collects new macro calls from this new AST piece and - adds them to the queue. - - ["Def paths"][defpath] are created and [`DefId`]s are - assigned to them by [`DefCollector`]. - - Names are put into modules (from the resolver's point of - view) by [`BuildReducedGraphVisitor`]. - 2. After expanding a single macro and integrating its output, continue - to the next iteration of [`fully_expand_fragment`][fef]. - 4. If it's not resolved: - 0. Put the macro back in the queue - 1. Continue to next iteration... +1. Initialize an `queue` of unresolved macros. +2. Repeat until `queue` is empty (or we make no progress, which is an error): + 1. [Resolve](./name-resolution.md) imports in our partially built crate as + much as possible. + 2. Collect as many macro [`Invocation`s][inv] as possible from our + partially built crate (fn-like, attributes, derives) and add them to the + queue. + 3. Dequeue the first element, and attempt to resolve it. + 4. If it's resolved: + 1. Run the macro's expander function that consumes a [`TokenStream`] or + AST and produces a [`TokenStream`] or [`AstFragment`] (depending on + the macro kind). (A `TokenStream` is a collection of [`TokenTree`s][tt], + each of which are a token (punctuation, identifier, or literal) or a + delimited group (anything inside `()`/`[]`/`{}`)). + - At this point, we know everything about the macro itself and can + call `set_expn_data` to fill in its properties in the global data; + that is the hygiene data associated with `ExpnId`. (See [the + "Hygiene" section below][hybelow]). + 2. Integrate that piece of AST into the big existing partially built + AST. This is essentially where the "token-like mass" becomes a + proper set-in-stone AST with side-tables. It happens as follows: + - If the macro produces tokens (e.g. a proc macro), we parse into + an AST, which may produce parse errors. + - During expansion, we create `SyntaxContext`s (hierarchy 2). (See + [the "Hygiene" section below][hybelow]) + - These three passes happen one after another on every AST fragment + freshly expanded from a macro: + - [`NodeId`]s are assigned by [`InvocationCollector`]. This + also collects new macro calls from this new AST piece and + adds them to the queue. + - ["Def paths"][defpath] are created and [`DefId`]s are + assigned to them by [`DefCollector`]. + - Names are put into modules (from the resolver's point of + view) by [`BuildReducedGraphVisitor`]. + 3. After expanding a single macro and integrating its output, continue + to the next iteration of [`fully_expand_fragment`][fef]. + 5. If it's not resolved: + 1. Put the macro back in the queue + 2. Continue to next iteration... [defpath]: hir.md#identifiers-in-the-hir [`NodeId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/node_id/struct.NodeId.html @@ -149,9 +149,9 @@ macros are implemented in [`rustc_builtin_macros`], along with some other early code generation facilities like injection of standard library imports or generation of test harness. There are some additional helpers for building their AST fragments in [`rustc_expand::build`][reb]. Eager expansion generally -performs a subset of the things that lazy (normal) expansion. It is done by +performs a subset of the things that lazy (normal) expansion does. It is done by invoking [`fully_expand_fragment`][fef] on only part of a crate (as opposed to -whole crate, like we normally do). +the whole crate, like we normally do). ### Other Data Structures @@ -532,7 +532,7 @@ three cases has occurred: - Failure: the token stream does not match `matcher`. This results in an error message such as "No rule expected token _blah_". - Error: some fatal error has occurred _in the parser_. For example, this - happens if there are more than one pattern match, since that indicates + happens if there is more than one pattern match, since that indicates the macro is ambiguous. The full interface is defined [here][code_parse_int]. diff --git a/src/doc/rustc-dev-guide/src/mir/dataflow.md b/src/doc/rustc-dev-guide/src/mir/dataflow.md index ce4a86a23..15bfd6aed 100644 --- a/src/doc/rustc-dev-guide/src/mir/dataflow.md +++ b/src/doc/rustc-dev-guide/src/mir/dataflow.md @@ -61,7 +61,7 @@ slower as a result. All implementers of `GenKillAnalysis` also implement ### Transfer Functions and Effects The dataflow framework in `rustc` allows each statement (and terminator) inside -a basic block define its own transfer function. For brevity, these +a basic block to define its own transfer function. For brevity, these individual transfer functions are known as "effects". Each effect is applied successively in dataflow order, and together they define the transfer function for the entire basic block. It's also possible to define an effect for diff --git a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md index 20b92cc45..0869e0e3d 100644 --- a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md +++ b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md @@ -111,7 +111,7 @@ a few optimizations: - Only paths that are the target of a `Drop` (or have the target as a prefix) need drop flags. -- Some variables are known to initialized (or uninitialized) when they are +- Some variables are known to be initialized (or uninitialized) when they are dropped. These do not need drop flags. - If a set of paths are only dropped or moved from via a shared prefix, those paths can share a single drop flag. diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md index 7fbdfd359..ceb0efdb2 100644 --- a/src/doc/rustc-dev-guide/src/overview.md +++ b/src/doc/rustc-dev-guide/src/overview.md @@ -292,7 +292,7 @@ Moreover, the compiler wasn't originally built to use a query system; the query system has been retrofitted into the compiler, so parts of it are not query-fied yet. Also, LLVM isn't our code, so that isn't querified either. The plan is to eventually query-fy all of the steps listed in the previous section, -but as of <!-- date-check --> November 2021, only the steps between HIR and +but as of <!-- date-check --> November 2022, only the steps between HIR and LLVM IR are query-fied. That is, lexing, parsing, name resolution, and macro expansion are done all at once for the whole program. diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md index e93f51dbb..e7cbbd7ee 100644 --- a/src/doc/rustc-dev-guide/src/parallel-rustc.md +++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md @@ -26,7 +26,7 @@ occurs in the `rustc_codegen_ssa::base` module. The underlying thread-safe data-structures used in the parallel compiler can be found in the `rustc_data_structures::sync` module. These data structures -are implemented diferently depending on whether `parallel-compiler` is true. +are implemented differently depending on whether `parallel-compiler` is true. | data structure | parallel | non-parallel | | -------------------------------- | --------------------------------------------------- | ------------ | @@ -141,7 +141,7 @@ the previous `Data Structures` and `Parallel Iterators`. See [this tracking issu ## Rustdoc -As of <!-- date-check--> May 2022, there are still a number of steps +As of <!-- date-check--> November 2022, there are still a number of steps to complete before rustdoc rendering can be made parallel. More details on this issue can be found [here][parallel-rustdoc]. diff --git a/src/doc/rustc-dev-guide/src/part-5-intro.md b/src/doc/rustc-dev-guide/src/part-5-intro.md index faa12f484..f32508d27 100644 --- a/src/doc/rustc-dev-guide/src/part-5-intro.md +++ b/src/doc/rustc-dev-guide/src/part-5-intro.md @@ -21,16 +21,16 @@ Now, we will finally take the MIR and produce some executable machine code. So what do we need to do? -0. First, we need to collect the set of things to generate code for. +1. First, we need to collect the set of things to generate code for. In particular, we need to find out which concrete types to substitute for generic ones, since we need to generate code for the concrete types. Generating code for the concrete types (i.e. emitting a copy of the code for each concrete type) is called _monomorphization_, so the process of collecting all the concrete types is called _monomorphization collection_. -1. Next, we need to actually lower the MIR to a codegen IR +2. Next, we need to actually lower the MIR to a codegen IR (usually LLVM IR) for each concrete type we collected. -2. Finally, we need to invoke the codegen backend, +3. Finally, we need to invoke the codegen backend, which runs a bunch of optimization passes, generates executable code, and links together an executable binary. diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md index dc196e490..abd2b0155 100644 --- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md @@ -175,11 +175,12 @@ fn try_mark_green(tcx, current_node) -> bool { true } - -// Note: The actual implementation can be found in -// compiler/rustc_middle/src/dep_graph/graph.rs ``` +> NOTE: +> The actual implementation can be found in +> [`compiler/rustc_query_system/src/dep_graph/graph.rs`][try_mark_green] + By using red-green marking we can avoid the devastating cumulative effect of having false positives during change detection. Whenever a query is executed in incremental mode, we first check if its already green. If not, we run @@ -187,7 +188,6 @@ in incremental mode, we first check if its already green. If not, we run invoke the query provider to re-compute the result. - ## The Real World: How Persistence Makes Everything Complicated The sections above described the underlying algorithm for incremental @@ -533,5 +533,5 @@ be reusable. See <https://github.com/rust-lang/rust/issues/47389> for more information. - [query-model]: ./query-evaluation-model-in-detail.html +[try_mark_green]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_query_system/dep_graph/graph.rs.html diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 3d60059bd..268a56558 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -169,31 +169,30 @@ they define both a `provide` and a `provide_extern` function, through How do you add a new query? Defining a query takes place in two steps: -1. Specify the query name and its arguments. +1. Declare the query name, its arguments and description. 2. Supply query providers where needed. -To specify the query name and arguments, you simply add an entry to -the big macro invocation in -[`compiler/rustc_middle/src/query/mod.rs`][query-mod], which looks something like: +To declare the query name and arguments, you simply add an entry to +the big macro invocation in [`compiler/rustc_middle/src/query/mod.rs`][query-mod]. +Then you need to add a documentation comment to it with some _internal_ description. +Then, provide the `desc` attribute which contains a _user-facing_ description of the query. +The `desc` attribute is shown to the user in query cycles. + +This looks something like: [query-mod]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/index.html ```rust,ignore rustc_queries! { - Other { - /// Records the type of every item. - query type_of(key: DefId) -> Ty<'tcx> { - cache { key.is_local() } - } + /// Records the type of every item. + query type_of(key: DefId) -> Ty<'tcx> { + cache_on_disk_if { key.is_local() } + desc { |tcx| "computing the type of `{}`", tcx.def_path_str(key) } } - ... } ``` -Queries are grouped into categories (`Other`, `Codegen`, `TypeChecking`, etc.). -Each group contains one or more queries. - A query definition has the following form: ```rust,ignore @@ -238,62 +237,6 @@ which is used to cheaply modify MIR in place. See the definition of `Steal` for more details. New uses of `Steal` should **not** be added without alerting `@rust-lang/compiler`. -### Query structs and descriptions - -For each query, the `rustc_queries` macro will generate a "query struct" -named after the query. This struct is a kind of placeholder -describing the query. Each query struct implements the -[`self::config::QueryConfig`][QueryConfig] trait, which has associated types for the -key/value of that particular query. Basically the code generated looks something -like this: - -```rust,ignore -// Dummy struct representing a particular kind of query: -pub struct type_of<'tcx> { data: PhantomData<&'tcx ()> } - -impl<'tcx> QueryConfig for type_of<'tcx> { - type Key = DefId; - type Value = Ty<'tcx>; - - const NAME: QueryName = QueryName::type_of; - const CATEGORY: ProfileCategory = ProfileCategory::Other; -} -``` - -There is an additional trait that you may wish to implement called -[`self::config::QueryDescription`][QueryDescription]. This trait is -used during cycle errors to give a "human readable" name for the query, -so that we can summarize what was happening when the cycle occurred. -Implementing this trait is optional if the query key is `DefId`, but -if you *don't* implement it, you get a pretty generic error ("processing `foo`..."). -You can put new impls into the `config` module. They look something like this: - -[QueryConfig]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_query_system/query/config/trait.QueryConfig.html -[QueryDescription]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_query_system/query/config/trait.QueryDescription.html - -```rust,ignore -impl<'tcx> QueryDescription for queries::type_of<'tcx> { - fn describe(tcx: TyCtxt, key: DefId) -> String { - format!("computing the type of `{}`", tcx.def_path_str(key)) - } -} -``` - -Another option is to add `desc` modifier: - -```rust,ignore -rustc_queries! { - Other { - /// Records the type of every item. - query type_of(key: DefId) -> Ty<'tcx> { - desc { |tcx| "computing the type of `{}`", tcx.def_path_str(key) } - } - } -} -``` - -`rustc_queries` macro will generate an appropriate `impl` automatically. - ## External links Related design ideas, and tracking issues: diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md index f21c8725c..c85e82e96 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md @@ -66,7 +66,7 @@ these passes, please let us know!) [44136]: https://github.com/rust-lang/rust/issues/44136 -Here is the list of passes as of <!-- date-check --> May 2022: +Here is the list of passes as of <!-- date-check --> November 2022: - `calculate-doc-coverage` calculates information used for the `--show-coverage` flag. diff --git a/src/doc/rustc-dev-guide/src/salsa.md b/src/doc/rustc-dev-guide/src/salsa.md index 872308e78..66f9d7479 100644 --- a/src/doc/rustc-dev-guide/src/salsa.md +++ b/src/doc/rustc-dev-guide/src/salsa.md @@ -9,7 +9,7 @@ want to watch [Salsa In More Depth](https://www.youtube.com/watch?v=i_IhACacPRY), also by Niko Matsakis. -> As of <!-- date-check --> April 2022, although Salsa is inspired by +> As of <!-- date-check --> November 2022, although Salsa is inspired by > (among other things) rustc's query system, it is not used directly in rustc. > It _is_ used in chalk and extensively in `rust-analyzer`, but there are no > medium or long-term concrete plans to integrate it into the compiler. diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md index b7308ee73..85c75fadb 100644 --- a/src/doc/rustc-dev-guide/src/stability.md +++ b/src/doc/rustc-dev-guide/src/stability.md @@ -72,14 +72,14 @@ Furthermore this attribute is needed to mark an intrinsic as callable from To stabilize a feature, follow these steps: -0. Ask a **@T-libs-api** member to start an FCP on the tracking issue and wait for +1. Ask a **@T-libs-api** member to start an FCP on the tracking issue and wait for the FCP to complete (with `disposition-merge`). -1. Change `#[unstable(...)]` to `#[stable(since = "CURRENT_RUSTC_VERSION")]`. -2. Remove `#![feature(...)]` from any test or doc-test for this API. If the feature is used in the +2. Change `#[unstable(...)]` to `#[stable(since = "CURRENT_RUSTC_VERSION")]`. +3. Remove `#![feature(...)]` from any test or doc-test for this API. If the feature is used in the compiler or tools, remove it from there as well. -3. If applicable, change `#[rustc_const_unstable(...)]` to +4. If applicable, change `#[rustc_const_unstable(...)]` to `#[rustc_const_stable(since = "CURRENT_RUSTC_VERSION")]`. -4. Open a PR against `rust-lang/rust`. +5. Open a PR against `rust-lang/rust`. - Add the appropriate labels: `@rustbot modify labels: +T-libs-api`. - Link to the tracking issue and say "Closes #XXXXX". diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index 1baa447a0..3556f4e23 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -207,6 +207,10 @@ There are several ways to match the message with the line (see the examples belo This is more convenient than using multiple carets when there are multiple messages associated with the same line. +The space character between `//~` (or other variants) and the subsequent text +is negligible (i.e. there is no semantic difference between `//~ ERROR` and +`//~ERROR` although the former is more common in the codebase). + ### Error annotation examples Here are examples of error annotations on different lines of UI test diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md index 88767ad94..9cf753b19 100644 --- a/src/doc/rustc-dev-guide/src/traits/resolution.md +++ b/src/doc/rustc-dev-guide/src/traits/resolution.md @@ -52,7 +52,7 @@ by proving that an appropriate impl does exist. During type checking, we do not store the results of trait selection. We simply wish to verify that trait selection will succeed. Then -later, at trans time, when we have all concrete types available, we +later, at codegen time, when we have all concrete types available, we can repeat the trait selection to choose an actual implementation, which will then be generated in the output binary. diff --git a/src/doc/rustc-dev-guide/src/traits/specialization.md b/src/doc/rustc-dev-guide/src/traits/specialization.md index 7a30314b4..7cae5e9c1 100644 --- a/src/doc/rustc-dev-guide/src/traits/specialization.md +++ b/src/doc/rustc-dev-guide/src/traits/specialization.md @@ -36,7 +36,7 @@ as long as they are part of the same specialization family. In that case, it returns a *single* impl on success – this is the most specialized impl *known* to apply. However, if there are any inference variables in play, the returned impl may not be the actual impl we -will use at trans time. Thus, we take special care to avoid projecting +will use at codegen time. Thus, we take special care to avoid projecting associated types unless either (1) the associated type does not use `default` and thus cannot be overridden or (2) all input types are known concretely. diff --git a/src/doc/rustc-dev-guide/src/ty-fold.md b/src/doc/rustc-dev-guide/src/ty-fold.md index c390597f9..dd76b80d4 100644 --- a/src/doc/rustc-dev-guide/src/ty-fold.md +++ b/src/doc/rustc-dev-guide/src/ty-fold.md @@ -17,7 +17,7 @@ and For example, the `TypeFolder` trait has a method [`fold_ty`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html#method.fold_ty) -that takes a type as input a type and returns a new type as a result. `TypeFoldable` invokes the +that takes a type as input and returns a new type as a result. `TypeFoldable` invokes the `TypeFolder` `fold_foo` methods on itself, giving the `TypeFolder` access to its contents (the types, regions, etc that are contained within). diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md index 10f1dd5ef..ca88c1686 100644 --- a/src/doc/rustc-dev-guide/src/type-inference.md +++ b/src/doc/rustc-dev-guide/src/type-inference.md @@ -218,29 +218,33 @@ algorithms. [`region_constraints`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/region_constraints/index.html [`opportunistic_resolve_var`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/region_constraints/struct.RegionConstraintCollector.html#method.opportunistic_resolve_var -## Extracting region constraints +## Solving region constraints -Ultimately, region constraints are only solved at the very end of -type-checking, once all other constraints are known. There are two +Region constraints are only solved at the very end of +typechecking, once all other constraints are known and +all other obligations have been proven. There are two ways to solve region constraints right now: lexical and non-lexical. Eventually there will only be one. +An exception here is the leak-check which is used during trait solving +and relies on region constraints containing higher-ranked regions. Region +constraints in the root universe (i.e. not arising from a `for<'a>`) must +not influence the trait system, as these regions are all erased during +codegen. + To solve **lexical** region constraints, you invoke [`resolve_regions_and_report_errors`]. This "closes" the region constraint process and invokes the [`lexical_region_resolve`] code. Once this is done, any further attempt to equate or create a subtyping relationship will yield an ICE. -Non-lexical region constraints are not handled within the inference -context. Instead, the NLL solver (actually, the MIR type-checker) -invokes [`take_and_reset_region_constraints`] periodically. This -extracts all of the outlives constraints from the region solver, but -leaves the set of variables intact. This is used to get *just* the -region constraints that resulted from some particular point in the -program, since the NLL solver needs to know not just *what* regions -were subregions, but also *where*. Finally, the NLL solver invokes -[`take_region_var_origins`], which "closes" the region constraint -process in the same way as normal solving. +The NLL solver (actually, the MIR type-checker) does things slightly +differently. It uses canonical queries for trait solving which use +[`take_and_reset_region_constraints`] at the end. This extracts all of the +outlives constraints added during the canonical query. This is required +as the NLL solver must not only know *what* regions outlive each other, +but also *where*. Finally, the NLL solver invokes [`take_region_var_origins`], +providing all region variables to the solver. [`resolve_regions_and_report_errors`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.resolve_regions_and_report_errors [`lexical_region_resolve`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/lexical_region_resolve/index.html |