summaryrefslogtreecommitdiffstats
path: root/src/doc/rustc-dev-guide
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/doc/rustc-dev-guide/.github/workflows/ci.yml21
-rw-r--r--src/doc/rustc-dev-guide/.github/workflows/date-check.yml2
-rw-r--r--src/doc/rustc-dev-guide/book.toml3
-rw-r--r--src/doc/rustc-dev-guide/ci/date-check/src/main.rs180
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md2
-rw-r--r--src/doc/rustc-dev-guide/src/about-this-guide.md4
-rw-r--r--src/doc/rustc-dev-guide/src/appendix/glossary.md3
-rw-r--r--src/doc/rustc-dev-guide/src/backend/backend-agnostic.md5
-rw-r--r--src/doc/rustc-dev-guide/src/backend/codegen.md19
-rw-r--r--src/doc/rustc-dev-guide/src/backend/debugging.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/updating-llvm.md18
-rw-r--r--src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md2
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping.md115
-rw-r--r--src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md14
-rw-r--r--src/doc/rustc-dev-guide/src/building/new-target.md8
-rw-r--r--src/doc/rustc-dev-guide/src/building/prerequisites.md10
-rw-r--r--src/doc/rustc-dev-guide/src/building/suggested.md6
-rw-r--r--src/doc/rustc-dev-guide/src/closure.md16
-rw-r--r--src/doc/rustc-dev-guide/src/compiler-debugging.md31
-rw-r--r--src/doc/rustc-dev-guide/src/const-eval.md62
-rw-r--r--src/doc/rustc-dev-guide/src/const-eval/interpret.md238
-rw-r--r--src/doc/rustc-dev-guide/src/contributing.md152
-rw-r--r--src/doc/rustc-dev-guide/src/conventions.md4
-rw-r--r--src/doc/rustc-dev-guide/src/crates-io.md16
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics.md12
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md79
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md248
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/lintstore.md45
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/translation.md45
-rw-r--r--src/doc/rustc-dev-guide/src/feature-gates.md4
-rw-r--r--src/doc/rustc-dev-guide/src/generics.md4
-rw-r--r--src/doc/rustc-dev-guide/src/git.md41
-rw-r--r--src/doc/rustc-dev-guide/src/img/rustc_stages.svg3
-rw-r--r--src/doc/rustc-dev-guide/src/implementing_new_features.md12
-rw-r--r--src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md7
-rw-r--r--src/doc/rustc-dev-guide/src/method-lookup.md4
-rw-r--r--src/doc/rustc-dev-guide/src/miri.md239
-rw-r--r--src/doc/rustc-dev-guide/src/name-resolution.md2
-rw-r--r--src/doc/rustc-dev-guide/src/opaque-types-impl-trait-inference.md6
-rw-r--r--src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md6
-rw-r--r--src/doc/rustc-dev-guide/src/overview.md6
-rw-r--r--src/doc/rustc-dev-guide/src/panic-implementation.md2
-rw-r--r--src/doc/rustc-dev-guide/src/parallel-rustc.md161
-rw-r--r--src/doc/rustc-dev-guide/src/part-5-intro.md65
-rw-r--r--src/doc/rustc-dev-guide/src/profiling.md2
-rw-r--r--src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md2
-rw-r--r--src/doc/rustc-dev-guide/src/query.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustc-driver.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc.md2
-rw-r--r--src/doc/rustc-dev-guide/src/salsa.md2
-rw-r--r--src/doc/rustc-dev-guide/src/stability.md6
-rw-r--r--src/doc/rustc-dev-guide/src/stabilization_guide.md26
-rw-r--r--src/doc/rustc-dev-guide/src/test-implementation.md1
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ci.md3
-rw-r--r--src/doc/rustc-dev-guide/src/tests/compiletest.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/intro.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/running.md12
-rw-r--r--src/doc/rustc-dev-guide/src/the-parser.md17
-rw-r--r--src/doc/rustc-dev-guide/src/thir.md163
-rw-r--r--src/doc/rustc-dev-guide/src/traits/chalk.md4
-rw-r--r--src/doc/rustc-dev-guide/src/traits/resolution.md117
-rw-r--r--src/doc/rustc-dev-guide/src/ty.md2
-rw-r--r--src/doc/rustc-dev-guide/src/type-inference.md10
66 files changed, 1302 insertions, 1005 deletions
diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml
index c571d408d..a21e342cb 100644
--- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml
+++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml
@@ -14,28 +14,28 @@ jobs:
if: github.repository == 'rust-lang/rustc-dev-guide'
runs-on: ubuntu-latest
env:
- MDBOOK_VERSION: 0.4.12
- MDBOOK_LINKCHECK_VERSION: 0.7.2
- MDBOOK_MERMAID_VERSION: 0.10.0
- MDBOOK_TOC_VERSION: 0.6.1
+ MDBOOK_VERSION: 0.4.21
+ MDBOOK_LINKCHECK_VERSION: 0.7.6
+ MDBOOK_MERMAID_VERSION: 0.11.2
+ MDBOOK_TOC_VERSION: 0.9.0
DEPLOY_DIR: book/html
BASE_SHA: ${{ github.event.pull_request.base.sha }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
with:
# linkcheck needs the base commit.
fetch-depth: 0
- name: Cache binaries
id: mdbook-cache
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: |
~/.cargo/bin
key: ${{ runner.os }}-${{ env.MDBOOK_VERSION }}--${{ env.MDBOOK_LINKCHECK_VERSION }}--${{ env.MDBOOK_TOC_VERSION }}--${{ env.MDBOOK_MERMAID_VERSION }}
- name: Cache linkcheck
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: |
~/book/linkcheck
@@ -49,10 +49,9 @@ jobs:
- name: Install latest nightly Rust toolchain
if: steps.mdbook-cache.outputs.cache-hit != 'true'
- uses: actions-rs/toolchain@v1
- with:
- toolchain: nightly
- override: true
+ run: |
+ rustup update nightly
+ rustup override set nightly
- name: Install Dependencies
if: steps.mdbook-cache.outputs.cache-hit != 'true'
diff --git a/src/doc/rustc-dev-guide/.github/workflows/date-check.yml b/src/doc/rustc-dev-guide/.github/workflows/date-check.yml
index b808876a4..c34c11c1e 100644
--- a/src/doc/rustc-dev-guide/.github/workflows/date-check.yml
+++ b/src/doc/rustc-dev-guide/.github/workflows/date-check.yml
@@ -15,7 +15,7 @@ jobs:
steps:
- name: Checkout repo
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Ensure Rust is up-to-date
run: |
diff --git a/src/doc/rustc-dev-guide/book.toml b/src/doc/rustc-dev-guide/book.toml
index 51dc8ecb0..dc216760e 100644
--- a/src/doc/rustc-dev-guide/book.toml
+++ b/src/doc/rustc-dev-guide/book.toml
@@ -15,7 +15,7 @@ command = "mdbook-mermaid"
[output.html]
git-repository-url = "https://github.com/rust-lang/rustc-dev-guide"
-edit-url-template = "https://github.com/rust-lang/rustc-dev-guide/tree/master/{path}?mode=edit"
+edit-url-template = "https://github.com/rust-lang/rustc-dev-guide/edit/master/{path}"
additional-js = ["mermaid.min.js", "mermaid-init.js"]
[output.html.fold]
@@ -43,3 +43,4 @@ warning-policy = "error"
[output.html.redirect]
"/compiletest.html" = "tests/compiletest.html"
"/diagnostics/sessiondiagnostic.html" = "diagnostics/diagnostic-structs.html"
+"/miri.html" = "const-eval/interpret.html"
diff --git a/src/doc/rustc-dev-guide/ci/date-check/src/main.rs b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
index bbea2bf38..70fce8b1c 100644
--- a/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
+++ b/src/doc/rustc-dev-guide/ci/date-check/src/main.rs
@@ -3,9 +3,11 @@ use std::{
convert::TryInto as _,
env, fmt, fs,
path::{Path, PathBuf},
+ process,
+ str::FromStr,
};
-use chrono::{Datelike as _, TimeZone as _, Utc};
+use chrono::{Datelike as _, Month, TimeZone as _, Utc};
use glob::glob;
use regex::Regex;
@@ -38,12 +40,18 @@ impl fmt::Display for Date {
fn make_date_regex() -> Regex {
Regex::new(
r"(?x) # insignificant whitespace mode
- <!--\s*
- [dD]ate:\s*
- (?P<y>\d{4}) # year
- -
- (?P<m>\d{2}) # month
- \s*-->",
+ (<!--\s*
+ date-check:\s*
+ (?P<m1>[[:alpha:]]+)\s+
+ (?P<y1>\d{4})\s*-->
+ )
+ |
+ (<!--\s*
+ date-check\s*-->\s+
+ (?P<m2>[[:alpha:]]+)\s+
+ (?P<y2>\d{4})\b
+ )
+ ",
)
.unwrap()
}
@@ -52,15 +60,22 @@ fn collect_dates_from_file(date_regex: &Regex, text: &str) -> Vec<(usize, Date)>
let mut line = 1;
let mut end_of_last_cap = 0;
date_regex
- .captures_iter(&text)
- .map(|cap| {
- (
- cap.get(0).unwrap().range(),
- Date {
- year: cap["y"].parse().unwrap(),
- month: cap["m"].parse().unwrap(),
- },
- )
+ .captures_iter(text)
+ .filter_map(|cap| {
+ if let (Some(month), Some(year), None, None) | (None, None, Some(month), Some(year)) = (
+ cap.name("m1"),
+ cap.name("y1"),
+ cap.name("m2"),
+ cap.name("y2"),
+ ) {
+ let year = year.as_str().parse().expect("year");
+ let month = Month::from_str(month.as_str())
+ .expect("month")
+ .number_from_month();
+ Some((cap.get(0).expect("all").range(), Date { year, month }))
+ } else {
+ None
+ }
})
.map(|(byte_range, date)| {
line += text[end_of_last_cap..byte_range.end]
@@ -110,9 +125,12 @@ fn filter_dates(
}
fn main() {
- let root_dir = env::args()
- .nth(1)
- .expect("expect root Markdown directory as CLI argument");
+ let mut args = env::args();
+ if args.len() == 1 {
+ eprintln!("error: expected root Markdown directory as CLI argument");
+ process::exit(1);
+ }
+ let root_dir = args.nth(1).unwrap();
let root_dir_path = Path::new(&root_dir);
let glob_pat = format!("{}/**/*.md", root_dir);
let today_chrono = Utc::today();
@@ -136,7 +154,7 @@ fn main() {
up-to-date. Each date should be updated (in the Markdown file where it appears) to \
use the current month ({current_month}), or removed if the docs it annotates are not \
expected to fall out of date quickly.",
- current_month = current_month
+ current_month = today_chrono.format("%B %Y"),
);
println!();
println!(
@@ -153,7 +171,7 @@ fn main() {
for (path, dates) in dates_by_file {
println!(
"- [ ] {}",
- path.strip_prefix(&root_dir_path).unwrap().display()
+ path.strip_prefix(&root_dir_path).unwrap_or(&path).display(),
);
for (line, date) in dates {
println!(" - [ ] line {}: {}", line, date);
@@ -182,61 +200,153 @@ mod tests {
#[test]
fn test_date_regex() {
- let regex = make_date_regex();
- assert!(regex.is_match("foo <!-- date: 2021-01 --> bar"));
+ let regex = &make_date_regex();
+ assert!(regex.is_match("<!-- date-check: jan 2021 -->"));
+ assert!(regex.is_match("<!-- date-check: january 2021 -->"));
+ assert!(regex.is_match("<!-- date-check: Jan 2021 -->"));
+ assert!(regex.is_match("<!-- date-check: January 2021 -->"));
+ assert!(regex.is_match("<!-- date-check --> jan 2021"));
+ assert!(regex.is_match("<!-- date-check --> january 2021"));
+ assert!(regex.is_match("<!-- date-check --> Jan 2021"));
+ assert!(regex.is_match("<!-- date-check --> January 2021"));
+
+ assert!(regex.is_match("<!-- date-check --> jan 2021 "));
+ assert!(regex.is_match("<!-- date-check --> jan 2021."));
}
#[test]
- fn test_date_regex_capitalized() {
- let regex = make_date_regex();
- assert!(regex.is_match("foo <!-- Date: 2021-08 --> bar"));
+ fn test_date_regex_fail() {
+ let regexes = &make_date_regex();
+ assert!(!regexes.is_match("<!-- date-check: jan 221 -->"));
+ assert!(!regexes.is_match("<!-- date-check: jan 20221 -->"));
+ assert!(!regexes.is_match("<!-- date-check: 01 2021 -->"));
+ assert!(!regexes.is_match("<!-- date-check --> jan 221"));
+ assert!(!regexes.is_match("<!-- date-check --> jan 20222"));
+ assert!(!regexes.is_match("<!-- date-check --> 01 2021"));
}
#[test]
fn test_collect_dates_from_file() {
- let text = "Test1\n<!-- date: 2021-01 -->\nTest2\nFoo<!-- date: 2021-02 \
- -->\nTest3\nTest4\nFoo<!-- date: 2021-03 -->Bar\n<!-- date: 2021-04 \
- -->\nTest5\nTest6\nTest7\n<!-- date: \n\n2021-05 -->\nTest8
+ let text = r"
+Test1
+<!-- date-check: jan 2021 -->
+Test2
+Foo<!-- date-check: february 2021
+-->
+Test3
+Test4
+Foo<!-- date-check: Mar 2021 -->Bar
+<!-- date-check:April 2021
+-->
+Test5
+Test6
+Test7
+<!-- date-check:
+
+may 2021 -->
+Test8
+Test1
+<!-- date-check --> jan 2021
+Test2
+Foo<!-- date-check
+--> february 2021
+Test3
+Test4
+Foo<!-- date-check --> mar 2021 Bar
+<!-- date-check
+--> apr 2021
+Test5
+Test6
+Test7
+<!-- date-check
+
+ --> may 2021
+Test8
+ <!--
+ date-check
+ --> june 2021.
";
assert_eq!(
collect_dates_from_file(&make_date_regex(), text),
vec![
(
- 2,
+ 3,
+ Date {
+ year: 2021,
+ month: 1,
+ }
+ ),
+ (
+ 6,
+ Date {
+ year: 2021,
+ month: 2,
+ }
+ ),
+ (
+ 9,
+ Date {
+ year: 2021,
+ month: 3,
+ }
+ ),
+ (
+ 11,
+ Date {
+ year: 2021,
+ month: 4,
+ }
+ ),
+ (
+ 17,
+ Date {
+ year: 2021,
+ month: 5,
+ }
+ ),
+ (
+ 20,
Date {
year: 2021,
month: 1,
}
),
(
- 4,
+ 23,
Date {
year: 2021,
month: 2,
}
),
(
- 7,
+ 26,
Date {
year: 2021,
month: 3,
}
),
(
- 8,
+ 28,
Date {
year: 2021,
month: 4,
}
),
(
- 14,
+ 34,
Date {
year: 2021,
month: 5,
}
),
- ]
+ (
+ 38,
+ Date {
+ year: 2021,
+ month: 6,
+ }
+ ),
+ ],
);
}
}
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index 99b24fe59..360265c0e 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -152,7 +152,7 @@
- [MIR optimizations](./mir/optimizations.md)
- [Debugging](./mir/debugging.md)
- [Constant evaluation](./const-eval.md)
- - [miri const evaluator](./miri.md)
+ - [Interpreter](./const-eval/interpret.md)
- [Monomorphization](./backend/monomorph.md)
- [Lowering MIR](./backend/lowering-mir.md)
- [Code Generation](./backend/codegen.md)
diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md
index b2c71866c..71407854e 100644
--- a/src/doc/rustc-dev-guide/src/about-this-guide.md
+++ b/src/doc/rustc-dev-guide/src/about-this-guide.md
@@ -5,7 +5,7 @@ as well as to help new contributors get involved in rustc development.
There are seven parts to this guide:
-1. [Building and debugging `rustc`][p1]:
+1. [Building `rustc`][p1]:
Contains information that should be useful no matter how you are contributing,
about building, debugging, profiling, etc.
2. [Contributing to `rustc`][p2]:
@@ -23,7 +23,7 @@ There are seven parts to this guide:
7. [Appendices][p7] at the end with useful reference information.
There are a few of these with different information, including a glossary.
-[p1]: ./getting-started.md
+[p1]: ./building/how-to-build-and-run.html
[p2]: ./contributing.md
[p3]: ./part-2-intro.md
[p4]: ./part-3-intro.md
diff --git a/src/doc/rustc-dev-guide/src/appendix/glossary.md b/src/doc/rustc-dev-guide/src/appendix/glossary.md
index 375db493c..42306dc1c 100644
--- a/src/doc/rustc-dev-guide/src/appendix/glossary.md
+++ b/src/doc/rustc-dev-guide/src/appendix/glossary.md
@@ -36,6 +36,7 @@ Term | Meaning
<span id="infcx">infcx</span> &nbsp; | The type inference context (`InferCtxt`). (see `rustc_middle::infer`)
<span id="inf-var">inference variable</span> &nbsp; | When doing type or region inference, an "inference variable" is a kind of special type/region that represents what you are trying to infer. Think of X in algebra. For example, if we are trying to infer the type of a variable in a program, we create an inference variable to represent that unknown type.
<span id="intern">intern</span> &nbsp; | Interning refers to storing certain frequently-used constant data, such as strings, and then referring to the data by an identifier (e.g. a `Symbol`) rather than the data itself, to reduce memory usage and number of allocations. See [this chapter](../memory.md) for more info.
+<span id="interpreter">interpreter</span> &nbsp; | The heart of const evaluation, running MIR code at compile time. ([see more](../const-eval/interpret.md))
<span id="intrinsic">intrinsic</span> &nbsp; | Intrinsics are special functions that are implemented in the compiler itself but exposed (often unstably) to users. They do magical and dangerous things. (See [`std::intrinsics`](https://doc.rust-lang.org/std/intrinsics/index.html))
<span id="ir">IR</span> &nbsp; | Short for Intermediate Representation, a general term in compilers. During compilation, the code is transformed from raw source (ASCII text) to various IRs. In Rust, these are primarily HIR, MIR, and LLVM IR. Each IR is well-suited for some set of computations. For example, MIR is well-suited for the borrow checker, and LLVM IR is well-suited for codegen because LLVM accepts it.
<span id="irlo">IRLO</span> &nbsp; | `IRLO` or `irlo` is sometimes used as an abbreviation for [internals.rust-lang.org](https://internals.rust-lang.org).
@@ -47,7 +48,7 @@ Term | Meaning
<span id="llvm">[LLVM]</span> &nbsp; | (actually not an acronym :P) an open-source compiler backend. It accepts LLVM IR and outputs native binaries. Various languages (e.g. Rust) can then implement a compiler front-end that outputs LLVM IR and use LLVM to compile to all the platforms LLVM supports.
<span id="memoization">memoization</span> &nbsp; | The process of storing the results of (pure) computations (such as pure function calls) to avoid having to repeat them in the future. This is typically a trade-off between execution speed and memory usage.
<span id="mir">MIR</span> &nbsp; | The Mid-level IR that is created after type-checking for use by borrowck and codegen. ([see more](../mir/index.md))
-<span id="miri">miri</span> &nbsp; | An interpreter for MIR used for constant evaluation. ([see more](../miri.md))
+<span id="miri">Miri</span> &nbsp; | A tool to detect Undefined Behavior in (unsafe) Rust code. ([see more](https://github.com/rust-lang/miri))
<span id="mono">monomorphization</span> &nbsp; | The process of taking generic implementations of types and functions and instantiating them with concrete types. For example, in the code we might have `Vec<T>`, but in the final executable, we will have a copy of the `Vec` code for every concrete type used in the program (e.g. a copy for `Vec<usize>`, a copy for `Vec<MyStruct>`, etc).
<span id="normalize">normalize</span> &nbsp; | A general term for converting to a more canonical form, but in the case of rustc typically refers to [associated type normalization](../traits/goals-and-clauses.md#normalizeprojection---type).
<span id="newtype">newtype</span> &nbsp; | A wrapper around some other type (e.g., `struct Foo(T)` is a "newtype" for `T`). This is commonly used in Rust to give a stronger type for indices.
diff --git a/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md b/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
index 271e6a16f..ea50cd754 100644
--- a/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
+++ b/src/doc/rustc-dev-guide/src/backend/backend-agnostic.md
@@ -2,15 +2,12 @@
<!-- toc -->
-As of <!-- date: 2021-10 --> October 2021, `rustc_codegen_ssa` provides an
+As of <!-- date-check --> Aug 2022, `rustc_codegen_ssa` provides an
abstract interface for all backends to implement, to allow other codegen
backends (e.g. [Cranelift]).
[Cranelift]: https://github.com/bytecodealliance/wasmtime/tree/HEAD/cranelift
-> The following is a copy/paste of a README from the rust-lang/rust repo.
-> Please submit a PR if it needs updating.
-
# Refactoring of `rustc_codegen_llvm`
by Denis Merigoux, October 23rd 2018
diff --git a/src/doc/rustc-dev-guide/src/backend/codegen.md b/src/doc/rustc-dev-guide/src/backend/codegen.md
index 1a6c2fa76..e2c92430e 100644
--- a/src/doc/rustc-dev-guide/src/backend/codegen.md
+++ b/src/doc/rustc-dev-guide/src/backend/codegen.md
@@ -1,13 +1,16 @@
# Code generation
-Code generation or "codegen" is the part of the compiler that actually
-generates an executable binary. Usually, rustc uses LLVM for code generation;
-there is also support for [Cranelift]. The key is that rustc doesn't implement
-codegen itself. It's worth noting, though, that in the Rust source code, many
-parts of the backend have `codegen` in their names (there are no hard
-boundaries).
-
-[Cranelift]: https://github.com/bytecodealliance/wasmtime/tree/HEAD/cranelift
+Code generation (or "codegen") is the part of the compiler
+that actually generates an executable binary.
+Usually, rustc uses LLVM for code generation,
+but there is also support for [Cranelift] and [GCC].
+The key is that rustc doesn't implement codegen itself.
+It's worth noting, though, that in the Rust source code,
+many parts of the backend have `codegen` in their names
+(there are no hard boundaries).
+
+[Cranelift]: https://github.com/bytecodealliance/wasmtime/tree/main/cranelift
+[GCC]: https://github.com/rust-lang/rustc_codegen_gcc
> NOTE: If you are looking for hints on how to debug code generation bugs,
> please see [this section of the debugging chapter][debugging].
diff --git a/src/doc/rustc-dev-guide/src/backend/debugging.md b/src/doc/rustc-dev-guide/src/backend/debugging.md
index 791a61fbe..26375204e 100644
--- a/src/doc/rustc-dev-guide/src/backend/debugging.md
+++ b/src/doc/rustc-dev-guide/src/backend/debugging.md
@@ -222,7 +222,7 @@ really helpful for this.
1. Once you have some LLVM IR for the problematic code (see above), you can
create a minimal working example with Godbolt. Go to
-[gcc.godbolt.org](https://gcc.godbolt.org).
+[llvm.godbolt.org](https://llvm.godbolt.org).
2. Choose `LLVM-IR` as programming language.
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 0de0767b6..81ebbbb40 100644
--- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
+++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
@@ -43,7 +43,7 @@ the branch we're already using. The steps for this are:
1. Make sure the bugfix is in upstream LLVM.
2. Identify the branch that rustc is currently using. The `src/llvm-project`
submodule is always pinned to a branch of the
- [rust-lang/llvm-project](https://github.com/rust-lang/llvm-project) repository.
+ [rust-lang/llvm-project repository].
3. Fork the rust-lang/llvm-project repository
4. Check out the appropriate branch (typically named `rustc/a.b-yyyy-mm-dd`)
5. Cherry-pick the upstream commit onto the branch
@@ -66,8 +66,8 @@ Example PRs look like:
## Feature updates
-> Note that this information is as of the time of this writing <!-- date:
-2021-10 --> (October 2021). The process for updating LLVM changes with
+> 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
@@ -146,9 +146,6 @@ easiest to land [`llvm-wrapper`] compatibility as a PR before actually updating
interested in trying out the new LLVM can benefit from work you've done to
update the C++ bindings.
-[rust-lang/llvm-project repository]: https://github.com/rust-lang/llvm-project
-[`llvm-wrapper`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_llvm/llvm-wrapper
-
### Caveats and gotchas
Ideally the above instructions are pretty smooth, but here's some caveats to
@@ -161,8 +158,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.
-[wg-llvm]: https://rust-lang.zulipchat.com/#narrow/stream/187780-t-compiler.2Fwg-llvm
-
## New LLVM Release Updates
Updating to a new release of LLVM is very similar to the "feature updates"
@@ -172,7 +167,7 @@ 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 https://github.com/llvm/llvm-project typically named
+ 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
@@ -192,3 +187,8 @@ typically looks like:
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
+[`llvm-wrapper`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_llvm/llvm-wrapper
+[wg-llvm]: https://rust-lang.zulipchat.com/#narrow/stream/187780-t-compiler.2Fwg-llvm
diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
index c7c107e1e..e236e0124 100644
--- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
+++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md
@@ -94,7 +94,7 @@ member constraints come in.
## Choices are always lifetime parameters
At present, the "choice" regions from a member constraint are always lifetime
-parameters from the current function. As of <!-- date: 2021-10 --> October 2021,
+parameters from the current function. As of <!-- date-check --> October 2021,
this falls out from the placement of impl Trait, though in the future it may not
be the case. We take some advantage of this fact, as it simplifies the current
code. In particular, we don't have to consider a case like `'0 member of ['1,
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping.md b/src/doc/rustc-dev-guide/src/building/bootstrapping.md
index fd54de20c..3bacc21d3 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping.md
@@ -18,7 +18,34 @@ rustc, then uses it to compile the new compiler.
## Stages of bootstrapping
-Compiling `rustc` is done in stages.
+Compiling `rustc` is done in stages. Here's a diagram, adapted from Joshua 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.
+<span style="background-color: lightblue; color: black">Blue</span> nodes are downloaded,
+<span style="background-color: yellow; color: black">yellow</span> nodes are built with the
+stage0 compiler, and
+<span style="background-color: lightgreen; color: black">green</span> nodes are built with the
+stage1 compiler.
+
+[rustconf22-talk]: https://rustconf.com/schedule#bootstrapping-the-once-and-future-compiler
+
+```mermaid
+graph TD
+ s0c["stage0 compiler (1.63)"]:::downloaded -->|A| s0l("stage0 std (1.64)"):::with-s0c;
+ s0c & s0l --- stepb[ ]:::empty;
+ stepb -->|B| s0ca["stage0 compiler artifacts (1.64)"]:::with-s0c;
+ s0ca -->|copy| s1c["stage1 compiler (1.64)"]:::with-s0c;
+ s1c -->|C| s1l("stage1 std (1.64)"):::with-s1c;
+ s1c & s1l --- stepd[ ]:::empty;
+ stepd -->|D| s1ca["stage1 compiler artifacts (1.64)"]:::with-s1c;
+ s1ca -->|copy| s2c["stage2 compiler"]:::with-s1c;
+
+ classDef empty width:0px,height:0px;
+ classDef downloaded fill: lightblue;
+ classDef with-s0c fill: yellow;
+ classDef with-s1c fill: lightgreen;
+```
### Stage 0
@@ -27,7 +54,7 @@ and its associated dynamic libraries,
which `x.py` will download for you.
(You can also configure `x.py` to use something else.)
-The stage0 compiler is then used only to compile `rustbuild`, `std`, and `rustc`.
+The stage0 compiler is then used only to compile `src/bootstrap`, `std`, and `rustc`.
When compiling `rustc`, the stage0 compiler uses the freshly compiled `std`.
There are two concepts at play here:
a compiler (with its set of dependencies)
@@ -46,9 +73,12 @@ In theory, the stage1 compiler is functionally identical to the stage2 compiler,
but in practice there are subtle differences.
In particular, the stage1 compiler itself was built by stage0
and hence not by the source in your working directory.
-This means that the symbol names used in the compiler source
-may not match the symbol names that would have been made by the stage1 compiler,
-which can cause problems for dynamic libraries and tests.
+This means that the ABI generated by the stage0 compiler may not match the ABI that would have been
+made by the stage1 compiler, which can cause problems for dynamic libraries, tests, and tools using
+`rustc_private`.
+
+Note that the `proc_macro` crate avoids this issue with a C FFI layer called `proc_macro::bridge`,
+allowing it to be used with stage 1.
The `stage2` compiler is the one distributed with `rustup` and all other install methods.
However, it takes a very long time to build
@@ -199,14 +229,6 @@ another program we are building with the stage N compiler:
`build --stage N compiler/rustc` is linking the stage N artifacts to the `std`
built by the stage N compiler.
-Here is a chart of a full build using `x.py`:
-
-<img alt="A diagram of the rustc compilation phases" src="../img/rustc_stages.svg" class="center" />
-
-Keep in mind this diagram is a simplification, i.e. `rustdoc` can be built at
-different stages, the process is a bit different when passing flags such as
-`--keep-stage`, or if there are non-host targets.
-
### Stages and `std`
Note that there are two `std` libraries in play here:
@@ -338,7 +360,7 @@ This flag has the following effects:
Code which does not use `-Z force-unstable-if-unmarked` should include the
`#![feature(rustc_private)]` crate attribute to access these force-unstable
-crates. This is needed for things that link `rustc`, such as `miri`, `rls`, or
+crates. This is needed for things that link `rustc`, such as `miri` or
`clippy`.
You can find more discussion about sysroots in:
@@ -348,9 +370,46 @@ You can find more discussion about sysroots in:
[rustdoc PR]: https://github.com/rust-lang/rust/pull/76728
-### Directories and artifacts generated by `x.py`
+## Passing flags to commands invoked by `bootstrap`
+
+`x.py` allows you to pass stage-specific flags to `rustc` and `cargo` when bootstrapping.
+The `RUSTFLAGS_BOOTSTRAP` environment variable is passed as `RUSTFLAGS` to the bootstrap stage
+(stage0), and `RUSTFLAGS_NOT_BOOTSTRAP` is passed when building artifacts for later stages.
+`RUSTFLAGS` will work, but also affects the build of `bootstrap` itself, so it will be rare to want
+to use it.
+Finally, `MAGIC_EXTRA_RUSTFLAGS` bypasses the `cargo` cache to pass flags to rustc without
+recompiling all dependencies.
+
+`RUSTDOCFLAGS`, `RUSTDOCFLAGS_BOOTSTRAP`, and `RUSTDOCFLAGS_NOT_BOOTSTRAP` are anologous to
+`RUSTFLAGS`, but for rustdoc.
+
+`CARGOFLAGS` will pass arguments to cargo itself (e.g. `--timings`). `CARGOFLAGS_BOOTSTRAP` and
+`CARGOFLAGS_NOT_BOOTSTRAP` work analogously to `RUSTFLAGS_BOOTSTRAP`.
+
+`--test-args` will pass arguments through to the test runner. For `src/test/ui`, this is
+compiletest; for unit tests and doctests this is the `libtest` runner. Most test runner accept
+`--help`, which you can use to find out the options accepted by the runner.
+
+## Environment Variables
+
+During bootstrapping, there are a bunch of compiler-internal environment
+variables that are used. If you are trying to run an intermediate version of
+`rustc`, sometimes you may need to set some of these environment variables
+manually. Otherwise, you get an error like the following:
+
+```text
+thread 'main' panicked at 'RUSTC_STAGE was not set: NotPresent', library/core/src/result.rs:1165:5
+```
+
+If `./stageN/bin/rustc` gives an error about environment variables, that
+usually means something is quite wrong -- or you're trying to compile e.g.
+`rustc` or `std` or something that depends on environment variables. In
+the unlikely case that you actually need to invoke rustc in such a situation,
+you can tell the bootstrap shim to print all env variables by adding `-vvv` to your `x.py` command.
+
+### Directories and artifacts generated by `bootstrap`
-The following tables indicate the outputs of various stage actions:
+This is an incomplete reference for the outputs generated by bootstrap:
| Stage 0 Action | Output |
|-----------------------------------------------------------|----------------------------------------------|
@@ -389,27 +448,3 @@ The following tables indicate the outputs of various stage actions:
| copy `rustdoc` | `build/HOST/stage2/bin` |
`--stage=2` stops here.
-
-## Passing stage-specific flags to `rustc`
-
-`x.py` allows you to pass stage-specific flags to `rustc` when bootstrapping.
-The `RUSTFLAGS_BOOTSTRAP` environment variable is passed as RUSTFLAGS to the bootstrap stage
-(stage0), and `RUSTFLAGS_NOT_BOOTSTRAP` is passed when building artifacts for later stages.
-
-## Environment Variables
-
-During bootstrapping, there are a bunch of compiler-internal environment
-variables that are used. If you are trying to run an intermediate version of
-`rustc`, sometimes you may need to set some of these environment variables
-manually. Otherwise, you get an error like the following:
-
-```text
-thread 'main' panicked at 'RUSTC_STAGE was not set: NotPresent', library/core/src/result.rs:1165:5
-```
-
-If `./stageN/bin/rustc` gives an error about environment variables, that
-usually means something is quite wrong -- or you're trying to compile e.g.
-`rustc` or `std` or something that depends on environment variables. In
-the unlikely case that you actually need to invoke rustc in such a situation,
-you can find the environment variable values by adding the following flag to
-your `x.py` command: `--on-fail=print-env`.
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 cce9d766a..c5cf3166d 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
@@ -150,8 +150,9 @@ This final product (stage1 compiler + libs built using that compiler)
is what you need to build other Rust programs (unless you use `#![no_std]` or
`#![no_core]`).
-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.
+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.
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
@@ -220,6 +221,15 @@ fall back to using `cargo` from the installed `nightly`, `beta`, or `stable` too
`rustup install nightly` if you haven't already. See the
[rustup documentation on custom toolchains](https://rust-lang.github.io/rustup/concepts/toolchains.html#custom-toolchains).
+**Note:** rust-analyzer and IntelliJ Rust plugin use a component called
+`rust-analyzer-proc-macro-srv` to work with proc macros. If you intend to use a
+custom toolchain for a project (e.g. via `rustup override set stage1`) you may
+want to build this component:
+
+```bash
+./x.py build proc-macro-srv-cli
+```
+
## Building targets for cross-compilation
To produce a compiler that can cross-compile for other targets,
diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md
index 77833fad1..f999a9472 100644
--- a/src/doc/rustc-dev-guide/src/building/new-target.md
+++ b/src/doc/rustc-dev-guide/src/building/new-target.md
@@ -102,15 +102,11 @@ unreleased version of `libc`, you can add it to the top-level
```diff
diff --git a/Cargo.toml b/Cargo.toml
-index be15e50e2bc..4fb1248ba99 100644
+index 1e83f05e0ca..4d0172071c1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
-@@ -66,10 +66,11 @@ cargo = { path = "src/tools/cargo" }
+@@ -113,6 +113,8 @@ cargo-util = { path = "src/tools/cargo/crates/cargo-util" }
[patch.crates-io]
- # Similar to Cargo above we want the RLS to use a vendored version of `rustfmt`
- # that we're shipping as well (to ensure that the rustfmt in RLS and the
- # `rustfmt` executable are the same exact version).
- rustfmt-nightly = { path = "src/tools/rustfmt" }
+libc = { git = "https://github.com/rust-lang/libc", rev = "0bf7ce340699dcbacabdf5f16a242d2219a49ee0" }
# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on
diff --git a/src/doc/rustc-dev-guide/src/building/prerequisites.md b/src/doc/rustc-dev-guide/src/building/prerequisites.md
index a5ab23d91..100b14aca 100644
--- a/src/doc/rustc-dev-guide/src/building/prerequisites.md
+++ b/src/doc/rustc-dev-guide/src/building/prerequisites.md
@@ -9,10 +9,12 @@ Before building the compiler, you need the following things installed:
* `git`
* `ssl` which comes in `libssl-dev` or `openssl-devel`
* `pkg-config` if you are compiling on Linux and targeting Linux
+* `libstdc++-static` may be required on some Linux distributions such as Fedora and Ubuntu
If building LLVM from source (the default), you'll need additional tools:
-* `g++` 5.1 or later, `clang++` 3.5 or later, or MSVC 2017 or later.
+* `g++`, `clang++`, or MSVC with versions listed on <!-- date-check: Aug 2022 -->
+ [LLVM's documentation](https://releases.llvm.org/13.0.0/docs/GettingStarted.html#host-c-toolchain-both-compiler-and-standard-library)
* `ninja`, or GNU `make` 3.81 or later (ninja is recommended, especially on Windows)
* `cmake` 3.13.4 or later
@@ -35,8 +37,10 @@ winget install -e Python.Python.3
winget install -e Kitware.CMake
```
-If any of those is installed already, winget will detect it.
-Then edit your systems `PATH` variable and add: `C:\Program Files\CMake\bin`.
+If any of those is installed already, winget will detect it. Then edit your system's `PATH` variable
+and add: `C:\Program Files\CMake\bin`. See
+[this guide on editing the system `PATH`](https://www.java.com/en/download/help/path.html) from the
+Java documentation.
For more information about building on Windows,
see [the `rust-lang/rust` README](https://github.com/rust-lang/rust#building-on-windows).
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index 1c2229335..5c5e571e4 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -22,7 +22,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: 2022-04 --><!-- the date comment is for the edition below -->
+you can write: <!-- date-check: apr 2022 --><!-- the date comment is for the edition below -->
```JSON
{
@@ -36,14 +36,18 @@ you can write: <!-- date: 2022-04 --><!-- the date comment is for the edition be
"./build/$TARGET_TRIPLE/stage0/bin/rustfmt",
"--edition=2021"
],
+ "rust-analyzer.procMacro.server": "./build/$TARGET_TRIPLE/stage0/libexec/rust-analyzer-proc-macro-srv",
"rust-analyzer.procMacro.enable": true,
"rust-analyzer.cargo.buildScripts.enable": true,
+ "rust-analyzer.cargo.buildScripts.invocationLocation": "root",
+ "rust-analyzer.cargo.buildScripts.invocationStrategy": "once",
"rust-analyzer.cargo.buildScripts.overrideCommand": [
"python3",
"x.py",
"check",
"--json-output"
],
+ "rust-analyzer.cargo.sysroot": "./build/$TARGET_TRIPLE/stage0-sysroot",
"rust-analyzer.rustc.source": "./Cargo.toml",
}
```
diff --git a/src/doc/rustc-dev-guide/src/closure.md b/src/doc/rustc-dev-guide/src/closure.md
index b43be3213..c3906a80b 100644
--- a/src/doc/rustc-dev-guide/src/closure.md
+++ b/src/doc/rustc-dev-guide/src/closure.md
@@ -135,10 +135,10 @@ appropriate trait: `Fn` trait for immutable borrow, `FnMut` for mutable borrow,
and `FnOnce` for move semantics.
Most of the code related to the closure is in the
-[`compiler/rustc_typeck/src/check/upvar.rs`][upvar] file and the data structures are
+[`compiler/rustc_hir_typeck/src/upvar.rs`][upvar] file and the data structures are
declared in the file [`compiler/rustc_middle/src/ty/mod.rs`][ty].
-[upvar]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/upvar/index.html
+[upvar]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/upvar/index.html
[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
@@ -146,12 +146,12 @@ codebase. For closures specifically, set the `RUST_LOG` env variable as below an
output in a file:
```console
-> RUST_LOG=rustc_typeck::check::upvar rustc +stage1 -Z dump-mir=all \
+> RUST_LOG=rustc_hir_typeck::upvar rustc +stage1 -Z dump-mir=all \
<.rs file to compile> 2> <file where the output will be dumped>
```
This uses the stage1 compiler and enables `debug!` logging for the
-`rustc_typeck::check::upvar` module.
+`rustc_hir_typeck::upvar` module.
The other option is to step through the code using lldb or gdb.
@@ -164,7 +164,7 @@ Let's start with [`upvar.rs`][upvar]. This file has something called
the [`euv::ExprUseVisitor`] which walks the source of the closure and
invokes a callback for each upvar that is borrowed, mutated, or moved.
-[`euv::ExprUseVisitor`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/expr_use_visitor/struct.ExprUseVisitor.html
+[`euv::ExprUseVisitor`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/expr_use_visitor/struct.ExprUseVisitor.html
```rust
fn main() {
@@ -210,6 +210,6 @@ self.tables
.extend(delegate.adjust_upvar_captures);
```
-[`Delegate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/expr_use_visitor/trait.Delegate.html
-[ibk]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/upvar/struct.InferBorrowKind.html
-[cmt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/mem_categorization/index.html
+[`Delegate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/expr_use_visitor/trait.Delegate.html
+[ibk]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/upvar/struct.InferBorrowKind.html
+[cmt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/mem_categorization/index.html
diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md
index 8f46e896e..35458b55c 100644
--- a/src/doc/rustc-dev-guide/src/compiler-debugging.md
+++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md
@@ -16,9 +16,36 @@ set `debug = true` in your config.toml.
Setting `debug = true` turns on many different debug options (e.g., `debug-assertions`,
`debug-logging`, etc.) which can be individually tweaked if you want to, but many people
-simply set `debug = true`. Check out the comments in config.toml.example for more info.
+simply set `debug = true`.
-You will need to rebuild the compiler once you've changed any configuration options.
+If you want to use GDB to debug rustc, please set `config.toml` with options:
+
+```toml
+[rust]
+debug = true
+debuginfo-level = 2
+```
+
+> NOTE:
+> This will use a lot of disk space
+> (upwards of <!-- date-check Aug 2022 --> 35GB),
+> and will take a lot more compile time.
+> With `debuginfo-level = 1` (the default when `debug = true`),
+> you will be able to track the execution path,
+> but will lose the symbol information for debugging.
+
+The default configuration will enable `symbol-mangling-version` v0.
+This requires at least GDB v10.2,
+otherwise you need to disable new symbol-mangling-version in `config.toml`.
+
+```toml
+[rust]
+new-symbol-mangling = false
+```
+
+> See the comments in `config.toml.example` for more info.
+
+You will need to rebuild the compiler after changing any configuration option.
## `-Z` flags
diff --git a/src/doc/rustc-dev-guide/src/const-eval.md b/src/doc/rustc-dev-guide/src/const-eval.md
index 5a11f8cdd..a7b1c8963 100644
--- a/src/doc/rustc-dev-guide/src/const-eval.md
+++ b/src/doc/rustc-dev-guide/src/const-eval.md
@@ -20,26 +20,72 @@ Additionally constant evaluation can be used to reduce the workload or binary
size at runtime by precomputing complex operations at compiletime and only
storing the result.
+All uses of constant evaluation can either be categorized as "influencing the type system"
+(array lengths, enum variant discriminants, const generic parameters), or as solely being
+done to precompute expressions to be used at runtime.
+
Constant evaluation can be done by calling the `const_eval_*` functions of `TyCtxt`.
They're the wrappers of the `const_eval` query.
+* `const_eval_global_id_for_typeck` evaluates a constant to a valtree,
+ so the result value can be further inspected by the compiler.
+* `const_eval_global_id` evaluate a constant to an "opaque blob" containing its final value;
+ this is only useful for codegen backends and the CTFE evaluator engine itself.
+* `eval_static_initializer` specifically computes the initial values of a static.
+ Statics are special; all other functions do not represent statics correctly
+ and have thus assertions preventing their use on statics.
+
The `const_eval_*` functions use a [`ParamEnv`](./param_env.html) of environment
in which the constant is evaluated (e.g. the function within which the constant is used)
and a [`GlobalId`]. The `GlobalId` is made up of an `Instance` referring to a constant
or static or of an `Instance` of a function and an index into the function's `Promoted` table.
-Constant evaluation returns a [`EvalToConstValueResult`] with either the error, or a
-representation of the constant. `static` initializers are always represented as
-[`miri`](./miri.html) virtual memory allocations (via [`ConstValue::ByRef`]).
-Other constants get represented as [`ConstValue::Scalar`]
-or [`ConstValue::Slice`] if possible. This means that the `const_eval_*`
-functions cannot be used to create miri-pointers to the evaluated constant.
-If you need the value of a constant inside Miri, you need to directly work with
-[`const_to_op`].
+Constant evaluation returns an [`EvalToValTreeResult`] for type system constants or
+[`EvalToConstValueResult`] with either the error, or a representation of the constant.
+
+Constants for the type system are encoded in "valtree representation". The `ValTree` datastructure
+allows us to represent
+
+* arrays,
+* many structs,
+* tuples,
+* enums and,
+* most primitives.
+
+The basic rule for
+being permitted in the type system is that every value must be uniquely represented. In other
+words: a specific value must only be representable in one specific way. For example: there is only
+one way to represent an array of two integers as a `ValTree`:
+`ValTree::Branch(&[ValTree::Leaf(first_int), ValTree;:Leaf(second_int)])`.
+Even though theoretically a `[u32; 2]` could be encoded in a `u64` and thus just be a
+`ValTree::Leaf(bits_of_two_u32)`, that is not a legal construction of `ValTree`
+(and is very complex to do, so it is unlikely anyone is tempted to do so).
+
+These rules also mean that some values are not representable. There can be no `union`s in type
+level constants, as it is not clear how they should be represented, because their active variant
+is unknown. Similarly there is no way to represent raw pointers, as addresses are unknown at
+compile-time and thus we cannot make any assumptions about them. References on the other hand
+*can* be represented, as equality for references is defined as equality on their value, so we
+ignore their address and just look at the backing value. We must make sure that the pointer values
+of the references are not observable at compile time. We thus encode `&42` exactly like `42`.
+Any conversion from
+valtree back to codegen constants must reintroduce an actual indirection. At codegen time the
+addresses may be deduplicated between multiple uses or not, entirely depending on arbitrary
+optimization choices.
+
+As a consequence, all decoding of `ValTree` must happen by matching on the type first and making
+decisions depending on that. The value itself gives no useful information without the type that
+belongs to it.
+
+Other constants get represented as [`ConstValue::Scalar`] or
+[`ConstValue::Slice`] if possible. These values are only useful outside the
+compile-time interpreter. If you need the value of a constant during
+interpretation, you need to directly work with [`const_to_op`].
[`GlobalId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/struct.GlobalId.html
[`ConstValue::Scalar`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/value/enum.ConstValue.html#variant.Scalar
[`ConstValue::Slice`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/value/enum.ConstValue.html#variant.Slice
[`ConstValue::ByRef`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/value/enum.ConstValue.html#variant.ByRef
[`EvalToConstValueResult`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/error/type.EvalToConstValueResult.html
+[`EvalToValTreeResult`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/error/type.EvalToValTreeResult.html
[`const_to_op`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/interpret/struct.InterpCx.html#method.const_to_op
diff --git a/src/doc/rustc-dev-guide/src/const-eval/interpret.md b/src/doc/rustc-dev-guide/src/const-eval/interpret.md
new file mode 100644
index 000000000..ee044505e
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/const-eval/interpret.md
@@ -0,0 +1,238 @@
+# Interpreter
+
+<!-- toc -->
+
+The interpreter is a virtual machine for executing MIR without compiling to
+machine code. It is usually invoked via `tcx.const_eval_*` functions. The
+interpreter is shared between the compiler (for compile-time function
+evaluation, CTFE) and the tool [Miri](https://github.com/rust-lang/miri/), which
+uses the same virtual machine to detect Undefined Behavior in (unsafe) Rust
+code.
+
+If you start out with a constant:
+
+```rust
+const FOO: usize = 1 << 12;
+```
+
+rustc doesn't actually invoke anything until the constant is either used or
+placed into metadata.
+
+Once you have a use-site like:
+
+```rust,ignore
+type Foo = [u8; FOO - 42];
+```
+
+The compiler needs to figure out the length of the array before being able to
+create items that use the type (locals, constants, function arguments, ...).
+
+To obtain the (in this case empty) parameter environment, one can call
+`let param_env = tcx.param_env(length_def_id);`. The `GlobalId` needed is
+
+```rust,ignore
+let gid = GlobalId {
+ promoted: None,
+ instance: Instance::mono(length_def_id),
+};
+```
+
+Invoking `tcx.const_eval(param_env.and(gid))` will now trigger the creation of
+the MIR of the array length expression. The MIR will look something like this:
+
+```mir
+Foo::{{constant}}#0: usize = {
+ let mut _0: usize;
+ let mut _1: (usize, bool);
+
+ bb0: {
+ _1 = CheckedSub(const FOO, const 42usize);
+ assert(!move (_1.1: bool), "attempt to subtract with overflow") -> bb1;
+ }
+
+ bb1: {
+ _0 = move (_1.0: usize);
+ return;
+ }
+}
+```
+
+Before the evaluation, a virtual memory location (in this case essentially a
+`vec![u8; 4]` or `vec![u8; 8]`) is created for storing the evaluation result.
+
+At the start of the evaluation, `_0` and `_1` are
+`Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef))`. This is quite
+a mouthful: [`Operand`] can represent either data stored somewhere in the
+[interpreter memory](#memory) (`Operand::Indirect`), or (as an optimization)
+immediate data stored in-line. And [`Immediate`] can either be a single
+(potentially uninitialized) [scalar value][`Scalar`] (integer or thin pointer),
+or a pair of two of them. In our case, the single scalar value is *not* (yet)
+initialized.
+
+When the initialization of `_1` is invoked, the value of the `FOO` constant is
+required, and triggers another call to `tcx.const_eval_*`, which will not be shown
+here. If the evaluation of FOO is successful, `42` will be subtracted from its
+value `4096` and the result stored in `_1` as
+`Operand::Immediate(Immediate::ScalarPair(Scalar::Raw { data: 4054, .. },
+Scalar::Raw { data: 0, .. })`. The first part of the pair is the computed value,
+the second part is a bool that's true if an overflow happened. A `Scalar::Raw`
+also stores the size (in bytes) of this scalar value; we are eliding that here.
+
+The next statement asserts that said boolean is `0`. In case the assertion
+fails, its error message is used for reporting a compile-time error.
+
+Since it does not fail, `Operand::Immediate(Immediate::Scalar(Scalar::Raw {
+data: 4054, .. }))` is stored in the virtual memory was allocated before the
+evaluation. `_0` always refers to that location directly.
+
+After the evaluation is done, the return value is converted from [`Operand`] to
+[`ConstValue`] by [`op_to_const`]: the former representation is geared towards
+what is needed *during* const evaluation, while [`ConstValue`] is shaped by the
+needs of the remaining parts of the compiler that consume the results of const
+evaluation. As part of this conversion, for types with scalar values, even if
+the resulting [`Operand`] is `Indirect`, it will return an immediate
+`ConstValue::Scalar(computed_value)` (instead of the usual `ConstValue::ByRef`).
+This makes using the result much more efficient and also more convenient, as no
+further queries need to be executed in order to get at something as simple as a
+`usize`.
+
+Future evaluations of the same constants will not actually invoke
+the interpreter, but just use the cached result.
+
+[`Operand`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/interpret/enum.Operand.html
+[`Immediate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/interpret/enum.Immediate.html
+[`ConstValue`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/enum.ConstValue.html
+[`Scalar`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/enum.Scalar.html
+[`op_to_const`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/const_eval/eval_queries/fn.op_to_const.html
+
+## Datastructures
+
+The interpreter's outside-facing datastructures can be found in
+[rustc_middle/src/mir/interpret](https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/mir/interpret).
+This is mainly the error enum and the [`ConstValue`] and [`Scalar`] types. A
+`ConstValue` can be either `Scalar` (a single `Scalar`, i.e., integer or thin
+pointer), `Slice` (to represent byte slices and strings, as needed for pattern
+matching) or `ByRef`, which is used for anything else and refers to a virtual
+allocation. These allocations can be accessed via the methods on
+`tcx.interpret_interner`. A `Scalar` is either some `Raw` integer or a pointer;
+see [the next section](#memory) for more on that.
+
+If you are expecting a numeric result, you can use `eval_usize` (panics on
+anything that can't be represented as a `u64`) or `try_eval_usize` which results
+in an `Option<u64>` yielding the `Scalar` if possible.
+
+## Memory
+
+To support any kind of pointers, the interpreter needs to have a "virtual memory" that the
+pointers can point to. This is implemented in the [`Memory`] type. In the
+simplest model, every global variable, stack variable and every dynamic
+allocation corresponds to an [`Allocation`] in that memory. (Actually using an
+allocation for every MIR stack variable would be very inefficient; that's why we
+have `Operand::Immediate` for stack variables that are both small and never have
+their address taken. But that is purely an optimization.)
+
+Such an `Allocation` is basically just a sequence of `u8` storing the value of
+each byte in this allocation. (Plus some extra data, see below.) Every
+`Allocation` has a globally unique `AllocId` assigned in `Memory`. With that, a
+[`Pointer`] consists of a pair of an `AllocId` (indicating the allocation) and
+an offset into the allocation (indicating which byte of the allocation the
+pointer points to). It may seem odd that a `Pointer` is not just an integer
+address, but remember that during const evaluation, we cannot know at which
+actual integer address the allocation will end up -- so we use `AllocId` as
+symbolic base addresses, which means we need a separate offset. (As an aside,
+it turns out that pointers at run-time are
+[more than just integers, too](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#pointer-provenance).)
+
+These allocations exist so that references and raw pointers have something to
+point to. There is no global linear heap in which things are allocated, but each
+allocation (be it for a local variable, a static or a (future) heap allocation)
+gets its own little memory with exactly the required size. So if you have a
+pointer to an allocation for a local variable `a`, there is no possible (no
+matter how unsafe) operation that you can do that would ever change said pointer
+to a pointer to a different local variable `b`.
+Pointer arithmetic on `a` will only ever change its offset; the `AllocId` stays the same.
+
+This, however, causes a problem when we want to store a `Pointer` into an
+`Allocation`: we cannot turn it into a sequence of `u8` of the right length!
+`AllocId` and offset together are twice as big as a pointer "seems" to be. This
+is what the `relocation` field of `Allocation` is for: the byte offset of the
+`Pointer` gets stored as a bunch of `u8`, while its `AllocId` gets stored
+out-of-band. The two are reassembled when the `Pointer` is read from memory.
+The other bit of extra data an `Allocation` needs is `undef_mask` for keeping
+track of which of its bytes are initialized.
+
+### Global memory and exotic allocations
+
+`Memory` exists only during evaluation; it gets destroyed when the
+final value of the constant is computed. In case that constant contains any
+pointers, those get "interned" and moved to a global "const eval memory" that is
+part of `TyCtxt`. These allocations stay around for the remaining computation
+and get serialized into the final output (so that dependent crates can use
+them).
+
+Moreover, to also support function pointers, the global memory in `TyCtxt` can
+also contain "virtual allocations": instead of an `Allocation`, these contain an
+`Instance`. That allows a `Pointer` to point to either normal data or a
+function, which is needed to be able to evaluate casts from function pointers to
+raw pointers.
+
+Finally, the [`GlobalAlloc`] type used in the global memory also contains a
+variant `Static` that points to a particular `const` or `static` item. This is
+needed to support circular statics, where we need to have a `Pointer` to a
+`static` for which we cannot yet have an `Allocation` as we do not know the
+bytes of its value.
+
+[`Memory`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/interpret/struct.Memory.html
+[`Allocation`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/struct.Allocation.html
+[`Pointer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/struct.Pointer.html
+[`GlobalAlloc`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/enum.GlobalAlloc.html
+
+### Pointer values vs Pointer types
+
+One common cause of confusion in the interpreter is that being a pointer *value* and having
+a pointer *type* are entirely independent properties. By "pointer value", we
+refer to a `Scalar::Ptr` containing a `Pointer` and thus pointing somewhere into
+the interpreter's virtual memory. This is in contrast to `Scalar::Raw`, which is just some
+concrete integer.
+
+However, a variable of pointer or reference *type*, such as `*const T` or `&T`,
+does not have to have a pointer *value*: it could be obtained by casting or
+transmuting an integer to a pointer.
+And similarly, when casting or transmuting a reference to some
+actual allocation to an integer, we end up with a pointer *value*
+(`Scalar::Ptr`) at integer *type* (`usize`). This is a problem because we
+cannot meaningfully perform integer operations such as division on pointer
+values.
+
+## Interpretation
+
+Although the main entry point to constant evaluation is the `tcx.const_eval_*`
+functions, there are additional functions in
+[rustc_const_eval/src/const_eval](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/index.html)
+that allow accessing the fields of a `ConstValue` (`ByRef` or otherwise). You should
+never have to access an `Allocation` directly except for translating it to the
+compilation target (at the moment just LLVM).
+
+The interpreter starts by creating a virtual stack frame for the current constant that is
+being evaluated. There's essentially no difference between a constant and a
+function with no arguments, except that constants do not allow local (named)
+variables at the time of writing this guide.
+
+A stack frame is defined by the `Frame` type in
+[rustc_const_eval/src/interpret/eval_context.rs](https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/eval_context.rs)
+and contains all the local
+variables memory (`None` at the start of evaluation). Each frame refers to the
+evaluation of either the root constant or subsequent calls to `const fn`. The
+evaluation of another constant simply calls `tcx.const_eval_*`, which produce an
+entirely new and independent stack frame.
+
+The frames are just a `Vec<Frame>`, there's no way to actually refer to a
+`Frame`'s memory even if horrible shenanigans are done via unsafe code. The only
+memory that can be referred to are `Allocation`s.
+
+The interpreter now calls the `step` method (in
+[rustc_const_eval/src/interpret/step.rs](https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/step.rs)
+) until it either returns an error or has no further statements to execute. Each
+statement will now initialize or modify the locals or the virtual memory
+referred to by a local. This might require evaluating other constants or
+statics, which just recursively invokes `tcx.const_eval_*`.
diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md
index 45f8c9033..279bc2f28 100644
--- a/src/doc/rustc-dev-guide/src/contributing.md
+++ b/src/doc/rustc-dev-guide/src/contributing.md
@@ -183,6 +183,7 @@ As a developer to this repository, you don't have to treat the following externa
differently from other crates that are directly in this repo:
* [Clippy](https://github.com/rust-lang/rust-clippy)
+* [Miri](https://github.com/rust-lang/miri)
* [rustfmt](https://github.com/rust-lang/rustfmt)
* [rust-analyzer](https://github.com/rust-lang/rust-analyzer)
@@ -249,37 +250,36 @@ subtrees) actually needs to use `git subtree`.
### External Dependencies (submodules)
-Currently building Rust will also build the following external projects:
+Building Rust will also use external git repositories tracked using [git
+submodules]. The complete list may be found in the [`.gitmodules`] file. Some
+of these projects are required (like `stdarch` for the standard library) and
+some of them are optional (like [Miri]).
-* [miri](https://github.com/rust-lang/miri)
-* [rls](https://github.com/rust-lang/rls/)
+Usage of submodules is discussed more in the [Using Git
+chapter](git.md#git-submodules).
-We allow breakage of these tools in the nightly channel. Maintainers of these
-projects will be notified of the breakages and should fix them as soon as
-possible.
-
-After the external is fixed, one could add the changes with
-
-```sh
-git add path/to/submodule
-```
-
-outside the submodule.
-
-In order to prepare your tool-fixing PR, you can run the build locally by doing
-`./x.py build src/tools/TOOL`. If you will be editing the sources
-there, you may wish to set `submodules = false` in the `config.toml`
-to prevent `x.py` from resetting to the original branch.
+Some of the submodules are allowed to be in a "broken" state where they
+either don't build or their tests don't pass, e.g. the documentation books
+like [The Rust Reference]. Maintainers of these projects will be notified
+when the project is in a broken state, and they should fix them as soon
+as possible. The current status is tracked on the [toolstate website].
+More information may be found on the Forge [Toolstate chapter].
Breakage is not allowed in the beta and stable channels, and must be addressed
-before the PR is merged.
+before the PR is merged. They are also not allowed to be broken on master in
+the week leading up to the beta cut.
+
+[git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
+[`.gitmodules`]: https://github.com/rust-lang/rust/blob/master/.gitmodules
+[The Rust Reference]: https://github.com/rust-lang/reference/
+[toolstate website]: https://rust-lang-nursery.github.io/rust-toolstate/
+[Toolstate chapter]: https://forge.rust-lang.org/infra/toolstate.html
#### Breaking Tools Built With The Compiler
Rust's build system builds a number of tools that make use of the internals of
the compiler and that are hosted in a separate repository, and included in Rust
-via git submodules. This includes [RLS](https://github.com/rust-lang/rls) and
-[Miri](https://github.com/rust-lang/Miri). If these tools break because of your
+via git submodules (such as [Miri]). If these tools break because of your
changes, you may run into a sort of "chicken and egg" problem. These tools rely
on the latest compiler to be built so you can't update them (in their own
repositories) to reflect your changes to the compiler until those changes are
@@ -299,7 +299,7 @@ done and the tools are working again, you go back in the compiler and update the
tools so they can be distributed again.
This should avoid a bunch of synchronization dances and is also much easier on contributors as
-there's no need to block on rls/miri/other tools changes going upstream.
+there's no need to block on tools changes going upstream.
Here are those same steps in detail:
@@ -309,8 +309,8 @@ Here are those same steps in detail:
from resetting to the original branch after you make your changes. If you
need to [update any submodules to their latest versions](#updating-submodules),
see the section of this file about that for more information.
-2. (optional) Run `./x.py test src/tools/rls` (substituting the submodule
- that broke for `rls`). Fix any errors in the submodule (and possibly others).
+2. (optional) Run `./x.py test src/tools/cargo` (substituting the submodule
+ that broke for `cargo`). Fix any errors in the submodule (and possibly others).
3. (optional) Make commits for your changes and send them to upstream repositories as a PR.
4. (optional) Maintainers of these submodules will **not** merge the PR. The PR can't be
merged because CI will be broken. You'll want to write a message on the PR referencing
@@ -320,71 +320,6 @@ Here are those same steps in detail:
7. (optional) Help land your PR on the upstream repository now that your changes are in nightly.
8. (optional) Send a PR to rust-lang/rust updating the submodule.
-#### Updating submodules
-
-These instructions are specific to updating `rls`, however they may apply
-to the other submodules as well. Please help by improving these instructions
-if you find any discrepancies or special cases that need to be addressed.
-
-To update the `rls` submodule, start by running the appropriate
-[`git submodule` command](https://git-scm.com/book/en/v2/Git-Tools-Submodules).
-For example, to update to the latest commit on the remote master branch,
-you may want to run:
-```
-git submodule update --remote src/tools/rls
-```
-If you run `./x.py build` now, and you are lucky, it may just work. If you see
-an error message about patches that did not resolve to any crates, you will need
-to complete a few more steps which are outlined with their rationale below.
-
-*(This error may change in the future to include more information.)*
-```
-error: failed to resolve patches for `https://github.com/rust-lang/rls`
-
-Caused by:
- patch for `rls` in `https://github.com/rust-lang/rls` did not resolve to any crates
-failed to run: ~/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo build --manifest-path ~/rust/src/bootstrap/Cargo.toml
-```
-
-The [`[patch]`][patchsec] section of `Cargo.toml` can be very useful for
-testing. In addition to that, you should read the [Overriding
-dependencies][overriding] section of the documentation.
-
-[patchsec]: http://doc.crates.io/manifest.html#the-patch-section
-[overriding]: http://doc.crates.io/specifying-dependencies.html#overriding-dependencies
-
-Specifically, the following [section in Overriding dependencies][testingbugfix]
-reveals what the problem is:
-
-[testingbugfix]: http://doc.crates.io/specifying-dependencies.html#testing-a-bugfix
-
-> Next up we need to ensure that our lock file is updated to use this new
-> version of uuid so our project uses the locally checked out copy instead of
-> one from crates.io. The way `[patch]` works is that it'll load the dependency
-> at ../path/to/uuid and then whenever crates.io is queried for versions of
-> uuid it'll also return the local version.
->
-> This means that the version number of the local checkout is significant and
-> will affect whether the patch is used. Our manifest declared uuid = "1.0"
-> which means we'll only resolve to >= 1.0.0, < 2.0.0, and Cargo's greedy
-> resolution algorithm also means that we'll resolve to the maximum version
-> within that range. Typically this doesn't matter as the version of the git
-> repository will already be greater or match the maximum version published on
-> crates.io, but it's important to keep this in mind!
-
-This says that when we updated the submodule, the version number in our
-`src/tools/rls/Cargo.toml` changed. The new version is different from
-the version in `Cargo.lock`, so the build can no longer continue.
-
-To resolve this, we need to update `Cargo.lock`. Luckily, cargo provides a
-command to do this easily.
-
-```
-$ cargo update -p rls
-```
-
-This should change the version listed in `Cargo.lock` to the new version you updated
-the submodule to. Running `./x.py build` should work now.
## Writing Documentation
@@ -437,17 +372,35 @@ Just a few things to keep in mind:
the project.
- The date the comment was added, e.g. instead of writing _"Currently, ..."_
- or _"As of now, ..."_, consider writing
- _"As of January 2021, ..."_.
- Try to format the date as `<MONTH> <YEAR>` to ease search.
+ or _"As of now, ..."_,
+ consider adding the date, in one of the following formats:
+ - Jan 2021
+ - January 2021
+ - jan 2021
+ - january 2021
+
+ There is a CI action (in `~/.github/workflows/date-check.yml`)
+ that generates a monthly issue with any of these that are over 6 months old.
+
+ For the action to pick the date,
+ add a special annotation before specifying the date:
+
+ ```md
+ <!-- date-check --> Jul 2022
+ ```
+
+ Example:
+
+ ```md
+ As of <!-- date-check --> Jul 2022, the foo did the bar.
+ ```
- - Additionally, include a machine-readable comment of the form `<!-- date:
- 2022-04 -->` (if the current month is April 2022). We have an automated
- tool that uses these (in `ci/date-check`).
+ For cases where the date should not be part of the visible rendered output,
+ use the following instead:
- So, for the month of April 2022, the comment would look like: `As of <!--
- date: 2022-04 --> April 2022`. Make sure to put the comment *between* `as of`
- and `April 2022`; see [PR #1066][rdg#1066] for the rationale.
+ ```md
+ <!-- date-check: Jul 2022 -->
+ ```
- A link to a relevant WG, tracking issue, `rustc` rustdoc page, or similar, that may provide
further explanation for the change process or a way to verify that the information is not
@@ -459,7 +412,6 @@ Just a few things to keep in mind:
[rdg]: https://rustc-dev-guide.rust-lang.org/
[rdgrepo]: https://github.com/rust-lang/rustc-dev-guide
-[rdg#1066]: https://github.com/rust-lang/rustc-dev-guide/pull/1066
## Issue Triage
diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md
index 15d125377..0d5f17b99 100644
--- a/src/doc/rustc-dev-guide/src/conventions.md
+++ b/src/doc/rustc-dev-guide/src/conventions.md
@@ -14,14 +14,14 @@ special config, so this may result in different style from normal [`rustfmt`].
Therefore, formatting this repository using `cargo fmt` is not recommended.
Instead, formatting should be done using `./x.py fmt`. It's a good habit to run
-`./x.py fmt` before every commit, as this reduces conflicts later.
+`./x.py fmt` before every commit, as this reduces conflicts later.
Formatting is checked by the `tidy` script. It runs automatically when you do
`./x.py test` and can be run in isolation with `./x.py fmt --check`.
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: 2022-04 --> `--edition=2021` argument yourself when calling
+pass the <!-- date-check: April 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/crates-io.md b/src/doc/rustc-dev-guide/src/crates-io.md
index 8c8fd0c38..f012c5bb5 100644
--- a/src/doc/rustc-dev-guide/src/crates-io.md
+++ b/src/doc/rustc-dev-guide/src/crates-io.md
@@ -1,20 +1,20 @@
# crates.io Dependencies
The Rust compiler supports building with some dependencies from `crates.io`.
-For example, `log` and `env_logger` come from `crates.io`.
+Examples are `log` and `env_logger`.
-In general, you should avoid adding dependencies to the compiler for several
-reasons:
+In general,
+you should avoid adding dependencies to the compiler for several reasons:
-- The dependency may not be high quality or well-maintained, whereas we want
- the compiler to be high-quality.
+- The dependency may not be of high quality or well-maintained.
- The dependency may not be using a compatible license.
- The dependency may have transitive dependencies that have one of the above
problems.
-As of <!-- date: 2022-02 --> February 2022, there is no official policy for vetting
-new dependencies to the compiler. Generally, new dependencies are not added
-to the compiler unless there is a good reason to do so.
+As of <!-- date-check --> Aug 2022,
+there is no official policy for vetting new dependencies to the compiler.
+Decisions are made on a case-by-case basis,
+during code review.
## Permitted dependencies
diff --git a/src/doc/rustc-dev-guide/src/diagnostics.md b/src/doc/rustc-dev-guide/src/diagnostics.md
index 0f0bfd895..e1d5fbe1a 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics.md
@@ -314,10 +314,10 @@ reporting errors.
[errors]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html
-Diagnostics can be implemented as types which implement the `SessionDiagnostic`
+Diagnostics can be implemented as types which implement the `IntoDiagnostic`
trait. This is preferred for new diagnostics as it enforces a separation
between diagnostic emitting logic and the main code paths. For less-complex
-diagnostics, the `SessionDiagnostic` trait can be derived -- see [Diagnostic
+diagnostics, the `IntoDiagnostic` trait can be derived -- see [Diagnostic
structs][diagnostic-structs]. Within the trait implementation, the APIs
described below can be used as normal.
@@ -388,10 +388,8 @@ In addition to telling the user exactly _why_ their code is wrong, it's
oftentimes furthermore possible to tell them how to fix it. To this end,
`DiagnosticBuilder` offers a structured suggestions API, which formats code
suggestions pleasingly in the terminal, or (when the `--error-format json` flag
-is passed) as JSON for consumption by tools, most notably the [Rust Language
-Server][rls] and [`rustfix`][rustfix].
+is passed) as JSON for consumption by tools like [`rustfix`][rustfix].
-[rls]: https://github.com/rust-lang/rls
[rustfix]: https://github.com/rust-lang/rustfix
Not all suggestions should be applied mechanically, they have a degree of
@@ -757,7 +755,7 @@ then dumped into the `Session::buffered_lints` used by the rest of the compiler.
The compiler accepts an `--error-format json` flag to output
diagnostics as JSON objects (for the benefit of tools such as `cargo
-fix` or the RLS). It looks like this:
+fix`). It looks like this:
```console
$ rustc json_error_demo.rs --error-format json
@@ -771,7 +769,7 @@ object, but the series of lines taken together is, unfortunately, not
valid JSON, thwarting tools and tricks (such as [piping to `python3 -m
json.tool`](https://docs.python.org/3/library/json.html#module-json.tool))
that require such. (One speculates that this was intentional for LSP
-performance purposes, so that each line/object can be sent to RLS as
+performance purposes, so that each line/object can be sent as
it is flushed?)
Also note the "rendered" field, which contains the "human" output as a
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md
index b6b6e0fa9..dcaba533e 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md
@@ -1,4 +1,5 @@
# Diagnostic Items
+
While writing lints it's common to check for specific types, traits and
functions. This raises the question on how to check for these. Types can be
checked by their complete type path. However, this requires hard coding paths
@@ -7,7 +8,8 @@ rustc has introduced diagnostic items that are used to identify types via
[`Symbol`]s.
## Finding diagnostic items
-Diagnostic items are added to items inside `rustc`/`std`/`core` with the
+
+Diagnostic items are added to items inside `rustc`/`std`/`core`/`alloc` with the
`rustc_diagnostic_item` attribute. The item for a specific type can be found by
opening the source code in the documentation and looking for this attribute.
Note that it's often added with the `cfg_attr` attribute to avoid compilation
@@ -19,12 +21,15 @@ errors during tests. A definition often looks like this:
struct Penguin;
```
-Diagnostic items are usually only added to traits, types and standalone
-functions. If the goal is to check for an associated type or method, please use
-the diagnostic item of the item and reference [*How To Use Diagnostic
-Items*](#how-to-use-diagnostic-items).
+Diagnostic items are usually only added to traits,
+types,
+and standalone functions.
+If the goal is to check for an associated type or method,
+please use the diagnostic item of the item and reference
+[*Using Diagnostic Items*](#using-diagnostic-items).
## Adding diagnostic items
+
A new diagnostic item can be added with these two steps:
1. Find the target item inside the Rust repo. Now add the diagnostic item as a
@@ -43,45 +48,55 @@ A new diagnostic item can be added with these two steps:
For the naming conventions of diagnostic items, please refer to
[*Naming Conventions*](#naming-conventions).
-2. As of <!-- date: 2022-02 --> February 2022, diagnostic items in code are
- accessed via symbols in [`rustc_span::symbol::sym`]. To add your newly
- created diagnostic item simply open the module file and add the name (In
- this case `Cat`) at the correct point in the list.
+2. <!-- date-check: Aug 2022 -->
+ Diagnostic items in code are accessed via symbols in
+ [`rustc_span::symbol::sym`].
+ To add your newly-created diagnostic item,
+ simply open the module file,
+ and add the name (In this case `Cat`) at the correct point in the list.
-Now you can create a pull request with your changes. :tada: (Note that when
-using diagnostic items in other projects like Clippy, it might take some time
-until the repos get synchronized.)
+Now you can create a pull request with your changes. :tada:
+
+> NOTE:
+> When using diagnostic items in other projects like Clippy,
+> it might take some time until the repos get synchronized.
## Naming conventions
-Diagnostic items don't have a set in stone naming convention yet. These are
-some guidelines that should be used for the future, but might differ from
-existing names:
-
-* Types, traits and enums are named using UpperCamelCase (Examples: `Iterator`,
-* `HashMap`, ...)
-* For type names that are used multiple times like `Writer` it's good to choose
- a more precise name, maybe by adding the module to it. (Example: `IoWriter`)
-* Associated items should not get their own diagnostic items, but instead be
- accessed indirectly by the diagnostic item of the type they're originating
- from.
+
+Diagnostic items don't have a naming convention yet.
+Following are some guidelines that should be used in future,
+but might differ from existing names:
+
+* Types, traits, and enums are named using UpperCamelCase
+ (Examples: `Iterator` and `HashMap`)
+* For type names that are used multiple times,
+ like `Writer`,
+ it's good to choose a more precise name,
+ maybe by adding the module to it
+ (Example: `IoWriter`)
+* Associated items should not get their own diagnostic items,
+ but instead be accessed indirectly by the diagnostic item
+ of the type they're originating from.
* Freestanding functions like `std::mem::swap()` should be named using
- `snake_case` with one important (export) module as a prefix (Example:
- `mem_swap`, `cmp_max`)
+ `snake_case` with one important (export) module as a prefix
+ (Examples: `mem_swap` and `cmp_max`)
* Modules should usually not have a diagnostic item attached to them.
- Diagnostic items were added to avoid the usage of paths, using them on
- modules would therefore most likely to be counterproductive.
+ Diagnostic items were added to avoid the usage of paths,
+ and using them on modules would therefore most likely be counterproductive.
## Using diagnostic items
+
In rustc, diagnostic items are looked up via [`Symbol`]s from inside the
[`rustc_span::symbol::sym`] module. These can then be mapped to [`DefId`]s
using [`TyCtxt::get_diagnostic_item()`] or checked if they match a [`DefId`]
using [`TyCtxt::is_diagnostic_item()`]. When mapping from a diagnostic item to
a [`DefId`], the method will return a `Option<DefId>`. This can be `None` if
either the symbol isn't a diagnostic item or the type is not registered, for
-instance when compiling with `#[no_std]`. All following examples are based on
-[`DefId`]s and their usage.
+instance when compiling with `#[no_std]`.
+All the following examples are based on [`DefId`]s and their usage.
### Example: Checking for a type
+
```rust
use rustc_span::symbol::sym;
@@ -96,6 +111,7 @@ fn example_1(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
```
### Example: Checking for a trait implementation
+
```rust
/// This example checks if a given [`DefId`] from a method is part of a trait
/// implementation defined by a diagnostic item.
@@ -112,6 +128,7 @@ fn is_diag_trait_item(
```
### Associated Types
+
Associated types of diagnostic items can be accessed indirectly by first
getting the [`DefId`] of the trait and then calling
[`TyCtxt::associated_items()`]. This returns an [`AssocItems`] object which can
@@ -119,13 +136,15 @@ be used for further checks. Checkout
[`clippy_utils::ty::get_iterator_item_ty()`] for an example usage of this.
### Usage in Clippy
+
Clippy tries to use diagnostic items where possible and has developed some
wrapper and utility functions. Please also refer to its documentation when
using diagnostic items in Clippy. (See [*Common tools for writing
lints*][clippy-Common-tools-for-writing-lints].)
## Related issues
-This lists some related issues. These are probably only interesting to people
+
+These are probably only interesting to people
who really want to take a deep dive into the topic :)
* [rust#60966]: The Rust PR that introduced diagnostic items
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 f28350e03..d51e79348 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
@@ -1,14 +1,14 @@
# Diagnostic and subdiagnostic structs
rustc has two diagnostic derives that can be used to create simple diagnostics,
which are recommended to be used when they are applicable:
-`#[derive(SessionDiagnostic)]` and `#[derive(SessionSubdiagnostic)]`.
+`#[derive(Diagnostic)]` and `#[derive(Subdiagnostic)]`.
Diagnostics created with the derive macros can be translated into different
languages and each has a slug that uniquely identifies the diagnostic.
-## `#[derive(SessionDiagnostic)]`
+## `#[derive(Diagnostic)]`
Instead of using the `DiagnosticBuilder` API to create and emit diagnostics,
-the `SessionDiagnostic` derive can be used. `#[derive(SessionDiagnostic)]` is
+the `Diagnostic` derive can be used. `#[derive(Diagnostic)]` is
only applicable for simple diagnostics that don't require much logic in
deciding whether or not to add additional subdiagnostics.
@@ -16,49 +16,47 @@ Consider the [definition][defn] of the "field already declared" diagnostic
shown below:
```rust,ignore
-#[derive(SessionDiagnostic)]
-#[error(typeck::field_already_declared, code = "E0124")]
+#[derive(Diagnostic)]
+#[diag(hir_analysis_field_already_declared, code = "E0124")]
pub struct FieldAlreadyDeclared {
pub field_name: Ident,
#[primary_span]
#[label]
pub span: Span,
- #[label = "previous-decl-label"]
+ #[label(hir_analysis_previous_decl_label)]
pub prev_span: Span,
}
```
-`SessionDiagnostic` can only be applied to structs. Every `SessionDiagnostic`
-has to have one attribute applied to the struct itself: either `#[error(..)]`
-for defining errors, or `#[warning(..)]` for defining warnings.
+`Diagnostic` can only be applied to structs. Every `Diagnostic`
+has to have one attribute, `#[diag(...)]`, applied to the struct itself.
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
-porting a diagnostic that uses `DiagnosticBuilder` to use `SessionDiagnostic`
+porting a diagnostic that uses `DiagnosticBuilder` to use `Diagnostic`
then you should keep the code if there was one.
-Both `#[error(..)]` and `#[warning(..)]` must provide a slug as the first
-positional argument (a path to an item in `rustc_errors::fluent::*`). A slug
-uniquely identifies the diagnostic and is also how the compiler knows what
-error message to emit (in the default locale of the compiler, or in the locale
-requested by the user). See [translation documentation](./translation.md) to
-learn more about how translatable error messages are written and how slug
-items are generated.
+`#[diag(..)]` must provide a slug as the first positional argument (a path to an
+item in `rustc_errors::fluent::*`). A slug uniquely identifies the diagnostic
+and is also how the compiler knows what error message to emit (in the default
+locale of the compiler, or in the locale requested by the user). See
+[translation documentation](./translation.md) to learn more about how
+translatable error messages are written and how slug items are generated.
In our example, the Fluent message for the "field already declared" diagnostic
looks like this:
```fluent
-typeck-field-already-declared =
+hir_analysis_field_already_declared =
field `{$field_name}` is already declared
.label = field already declared
- .previous-decl-label = `{$field_name}` first declared here
+ .previous_decl_label = `{$field_name}` first declared here
```
-`typeck-field-already-declared` is the slug from our example and is followed
+`hir_analysis_field_already_declared` is the slug from our example and is followed
by the diagnostic message.
-Every field of the `SessionDiagnostic` which does not have an annotation is
+Every field of the `Diagnostic` which does not have an annotation is
available in Fluent messages as a variable, like `field_name` in the example
above. Fields can be annotated `#[skip_arg]` if this is undesired.
@@ -68,19 +66,19 @@ of the diagnostic.
Diagnostics are more than just their primary message, they often include
labels, notes, help messages and suggestions, all of which can also be
-specified on a `SessionDiagnostic`.
+specified on a `Diagnostic`.
`#[label]`, `#[help]` and `#[note]` can all be applied to fields which have the
type `Span`. Applying any of these attributes will create the corresponding
subdiagnostic with that `Span`. These attributes will look for their
diagnostic message in a Fluent attribute attached to the primary Fluent
message. In our example, `#[label]` will look for
-`typeck-field-already-declared.label` (which has the message "field already
+`hir_analysis_field_already_declared.label` (which has the message "field already
declared"). If there is more than one subdiagnostic of the same type, then
these attributes can also take a value that is the attribute name to look for
-(e.g. `previous-decl-label` in our example).
+(e.g. `previous_decl_label` in our example).
-Other types have special behavior when used in a `SessionDiagnostic` derive:
+Other types have special behavior when used in a `Diagnostic` derive:
- Any attribute applied to an `Option<T>` and will only emit a
subdiagnostic if the option is `Some(..)`.
@@ -95,38 +93,35 @@ represent optional `#[note]`/`#[help]` subdiagnostics.
Suggestions can be emitted using one of four field attributes:
-- `#[suggestion(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_hidden(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_short(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_verbose(message = "...", code = "...", applicability = "...")]`
+- `#[suggestion(slug, code = "...", applicability = "...")]`
+- `#[suggestion_hidden(slug, code = "...", applicability = "...")]`
+- `#[suggestion_short(slug, code = "...", applicability = "...")]`
+- `#[suggestion_verbose(slug, code = "...", applicability = "...")]`
Suggestions must be applied on either a `Span` field or a `(Span,
-MachineApplicability)` field. Similarly to other field attributes, `message`
-specifies the Fluent attribute with the message and defaults to `.suggestion`.
-`code` specifies the code that should be suggested as a replacement and is a
-format string (e.g. `{field_name}` would be replaced by the value of the
-`field_name` field of the struct), not a Fluent identifier. `applicability` can
-be used to specify the applicability in the attribute, it cannot be used when
-the field's type contains an `Applicability`.
+MachineApplicability)` field. Similarly to other field attributes, the slug
+specifies the Fluent attribute with the message and defaults to the equivalent
+of `.suggestion`. `code` specifies the code that should be suggested as a
+replacement and is a format string (e.g. `{field_name}` would be replaced by
+the value of the `field_name` field of the struct), not a Fluent identifier.
+`applicability` can be used to specify the applicability in the attribute, it
+cannot be used when the field's type contains an `Applicability`.
-In the end, the `SessionDiagnostic` derive will generate an implementation of
-`SessionDiagnostic` that looks like the following:
+In the end, the `Diagnostic` derive will generate an implementation of
+`IntoDiagnostic` that looks like the following:
```rust,ignore
-impl SessionDiagnostic for FieldAlreadyDeclared {
- fn into_diagnostic(self, sess: &'_ rustc_session::Session) -> DiagnosticBuilder<'_> {
- let mut diag = sess.struct_err_with_code(
- rustc_errors::DiagnosticMessage::fluent("typeck-field-already-declared"),
- rustc_errors::DiagnosticId::Error("E0124")
- );
+impl IntoDiagnostic<'_> for FieldAlreadyDeclared {
+ fn into_diagnostic(self, handler: &'_ rustc_errors::Handler) -> DiagnosticBuilder<'_> {
+ let mut diag = handler.struct_err(rustc_errors::fluent::hir_analysis_field_already_declared);
diag.set_span(self.span);
diag.span_label(
self.span,
- rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "label")
+ rustc_errors::fluent::hir_analysis_label
);
diag.span_label(
self.prev_span,
- rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "previous-decl-label")
+ rustc_errors::fluent::hir_analysis_previous_decl_label
);
diag
}
@@ -146,52 +141,63 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
```
### Reference
-`#[derive(SessionDiagnostic)]` supports the following attributes:
+`#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` support the
+following attributes:
-- `#[error(slug, code = "...")]` or `#[warning(slug, code = "...")]`
- - _Applied to struct._
+- `#[diag(slug, code = "...")]`
+ - _Applied to struct or enum variant._
- _Mandatory_
- - Defines the struct to be representing an error or a warning.
+ - Defines the text and error code to be associated with the diagnostic.
- Slug (_Mandatory_)
- Uniquely identifies the diagnostic and corresponds to its Fluent message,
mandatory.
- - A path to an item in `rustc_errors::fluent`. Always in a module starting
- with a Fluent resource name (which is typically the name of the crate
- that the diagnostic is from), e.g.
- `rustc_errors::fluent::typeck::field_already_declared`
+ - A path to an item in `rustc_errors::fluent`, e.g.
+ `rustc_errors::fluent::hir_analysis_field_already_declared`
(`rustc_errors::fluent` is implicit in the attribute, so just
- `typeck::field_already_declared`).
+ `hir_analysis_field_already_declared`).
- See [translation documentation](./translation.md).
- `code = "..."` (_Optional_)
- Specifies the error code.
-- `#[note]` or `#[note = "..."]` (_Optional_)
+- `#[note]` or `#[note(slug)]` (_Optional_)
- _Applied to struct or `Span`/`()` fields._
- Adds a note subdiagnostic.
- - Value is the Fluent attribute (relative to the Fluent message specified by
- `slug`) for the note's message
- - Defaults to `note`.
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.note`.
- If applied to a `Span` field, creates a spanned note.
-- `#[help]` or `#[help = "..."]` (_Optional_)
+- `#[help]` or `#[help(slug)]` (_Optional_)
- _Applied to struct or `Span`/`()` fields._
- Adds a help subdiagnostic.
- - Value is the Fluent attribute (relative to the Fluent message specified by
- `slug`) for the help's message.
- - Defaults to `help`.
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.help`.
- If applied to a `Span` field, creates a spanned help.
-- `#[label]` or `#[label = "..."]` (_Optional_)
+- `#[label]` or `#[label(slug)]` (_Optional_)
- _Applied to `Span` fields._
- Adds a label subdiagnostic.
- - Value is the Fluent attribute (relative to the Fluent message specified by
- `slug`) for the label's message.
- - Defaults to `label`.
-- `#[suggestion{,_hidden,_short,_verbose}(message = "...", code = "...", applicability = "...")]`
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.label`.
+- `#[warn_]` or `#[warn_(slug)]` (_Optional_)
+ - _Applied to `Span` fields._
+ - Adds a warning subdiagnostic.
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.warn`.
+- `#[suggestion{,_hidden,_short,_verbose}(slug, code = "...", applicability = "...")]`
(_Optional_)
- _Applied to `(Span, MachineApplicability)` or `Span` fields._
- Adds a suggestion subdiagnostic.
- - `message = "..."` (_Mandatory_)
- - Value is the Fluent attribute (relative to the Fluent message specified
- by `slug`) for the suggestion's message.
- - Defaults to `suggestion`.
+ - Slug (_Mandatory_)
+ - A path to an item in `rustc_errors::fluent`, e.g.
+ `rustc_errors::fluent::hir_analysis_field_already_declared`
+ (`rustc_errors::fluent` is implicit in the attribute, so just
+ `hir_analysis_field_already_declared`). Fluent attributes for all messages
+ exist as top-level items in that module (so `hir_analysis_message.attr` is just
+ `attr`).
+ - 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.
@@ -200,20 +206,20 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
`has-placeholders` or `unspecified`.
- `#[subdiagnostic]`
- _Applied to a type that implements `AddToDiagnostic` (from
- `#[derive(SessionSubdiagnostic)]`)._
+ `#[derive(Subdiagnostic)]`)._
- Adds the subdiagnostic represented by the subdiagnostic struct.
- `#[primary_span]` (_Optional_)
- - _Applied to `Span` fields._
+ - _Applied to `Span` fields on `Subdiagnostic`s. Not used for `LintDiagnostic`s._
- Indicates the primary span of the diagnostic.
- `#[skip_arg]` (_Optional_)
- _Applied to any field._
- Prevents the field from being provided as a diagnostic argument.
-## `#[derive(SessionSubdiagnostic)]`
+## `#[derive(Subdiagnostic)]`
It is common in the compiler to write a function that conditionally adds a
specific subdiagnostic to an error if it is applicable. Oftentimes these
subdiagnostics could be represented using a diagnostic struct even if the
-overall diagnostic could not. In this circumstance, the `SessionSubdiagnostic`
+overall diagnostic could not. In this circumstance, the `Subdiagnostic`
derive can be used to represent a partial diagnostic (e.g a note, label, help or
suggestion) as a struct.
@@ -221,14 +227,14 @@ Consider the [definition][subdiag_defn] of the "expected return type" label
shown below:
```rust
-#[derive(SessionSubdiagnostic)]
+#[derive(Subdiagnostic)]
pub enum ExpectedReturnTypeLabel<'tcx> {
- #[label(typeck::expected_default_return_type)]
+ #[label(hir_analysis_expected_default_return_type)]
Unit {
#[primary_span]
span: Span,
},
- #[label(typeck::expected_return_type)]
+ #[label(hir_analysis_expected_return_type)]
Other {
#[primary_span]
span: Span,
@@ -237,9 +243,9 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
}
```
-Unlike `SessionDiagnostic`, `SessionSubdiagnostic` can be applied to structs or
+Unlike `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 `SessionSubdiagnostic` should have one
+variants for enums (or vice versa). Each `Subdiagnostic` should have one
attribute applied to the struct or each variant, one of:
- `#[label(..)]` for defining a label
@@ -258,9 +264,9 @@ In our example, the Fluent message for the "expected return type" label
looks like this:
```fluent
-typeck-expected-default-return-type = expected `()` because of default return type
+hir_analysis_expected_default_return_type = expected `()` because of default return type
-typeck-expected-return-type = expected `{$expected}` because of return type
+hir_analysis_expected_return_type = expected `{$expected}` because of return type
```
Using the `#[primary_span]` attribute on a field (with type `Span`) will denote
@@ -271,21 +277,22 @@ Every field of the type/variant which does not have an annotation is available
in Fluent messages as a variable. Fields can be annotated `#[skip_arg]` if this
is undesired.
-Like `SessionDiagnostic`, `SessionSubdiagnostic` supports `Option<T>` and
+Like `Diagnostic`, `Subdiagnostic` supports `Option<T>` and
`Vec<T>` fields.
Suggestions can be emitted using one of four attributes on the type/variant:
-- `#[suggestion(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_hidden(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_short(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_verbose(message = "...", code = "...", applicability = "...")]`
+- `#[suggestion(..., code = "...", applicability = "...")]`
+- `#[suggestion_hidden(..., code = "...", applicability = "...")]`
+- `#[suggestion_short(..., code = "...", applicability = "...")]`
+- `#[suggestion_verbose(..., code = "...", applicability = "...")]`
Suggestions require `#[primary_span]` be set on a field and can have the
following sub-attributes:
-- `message` specifies the Fluent attribute with the message and defaults to
- `.suggestion`.
+- The first positional argument specifies the path to a item in
+ `rustc_errors::fluent` corresponding to the Fluent attribute with the message
+ and defaults to the equivalent of `.suggestion`.
- `code` specifies the code that should be suggested as a replacement and is a
format string (e.g. `{field_name}` would be replaced by the value of the
`field_name` field of the struct), not a Fluent identifier.
@@ -295,8 +302,8 @@ following sub-attributes:
Applicabilities can also be specified as a field (of type `Applicability`)
using the `#[applicability]` attribute.
-In the end, the `SessionSubdiagnostic` derive will generate an implementation
-of `SessionSubdiagnostic` that looks like the following:
+In the end, the `Subdiagnostic` derive will generate an implementation
+of `AddToDiagnostic` that looks like the following:
```rust
impl<'tcx> AddToDiagnostic for ExpectedReturnTypeLabel<'tcx> {
@@ -304,11 +311,11 @@ impl<'tcx> AddToDiagnostic for ExpectedReturnTypeLabel<'tcx> {
use rustc_errors::{Applicability, IntoDiagnosticArg};
match self {
ExpectedReturnTypeLabel::Unit { span } => {
- diag.span_label(span, DiagnosticMessage::fluent("typeck-expected-default-return-type"))
+ diag.span_label(span, rustc_errors::fluent::hir_analysis_expected_default_return_type)
}
ExpectedReturnTypeLabel::Other { span, expected } => {
diag.set_arg("expected", expected);
- diag.span_label(span, DiagnosticMessage::fluent("typeck-expected-return-type"))
+ diag.span_label(span, rustc_errors::fluent::hir_analysis_expected_return_type)
}
}
@@ -322,7 +329,7 @@ diagnostic or by assigning it to a `#[subdiagnostic]`-annotated field of a
diagnostic struct.
### Reference
-`#[derive(SessionSubdiagnostic)]` supports the following attributes:
+`#[derive(Subdiagnostic)]` supports the following attributes:
- `#[label(slug)]`, `#[help(slug)]` or `#[note(slug)]`
- _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
@@ -331,21 +338,25 @@ diagnostic struct.
- Slug (_Mandatory_)
- Uniquely identifies the diagnostic and corresponds to its Fluent message,
mandatory.
- - A path to an item in `rustc_errors::fluent`. Always in a module starting
- with a Fluent resource name (which is typically the name of the crate
- that the diagnostic is from), e.g.
- `rustc_errors::fluent::typeck::field_already_declared`
+ - A path to an item in `rustc_errors::fluent`, e.g.
+ `rustc_errors::fluent::hir_analysis_field_already_declared`
(`rustc_errors::fluent` is implicit in the attribute, so just
- `typeck::field_already_declared`).
+ `hir_analysis_field_already_declared`).
- See [translation documentation](./translation.md).
-- `#[suggestion{,_hidden,_short,_verbose}(message = "...", code = "...", applicability = "...")]`
+- `#[suggestion{,_hidden,_short,_verbose}(slug, code = "...", applicability = "...")]`
- _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
- _Mandatory_
- Defines the type to be representing a suggestion.
- - `message = "..."` (_Mandatory_)
- - Value is the Fluent attribute (relative to the Fluent message specified
- by `slug`) for the suggestion's message.
- - Defaults to `suggestion`.
+ - Slug (_Mandatory_)
+ - A path to an item in `rustc_errors::fluent`, e.g.
+ `rustc_errors::fluent::hir_analysis_field_already_declared`
+ (`rustc_errors::fluent` is implicit in the attribute, so just
+ `hir_analysis::field_already_declared`). Fluent attributes for all messages
+ exist as top-level items in that module (so `hir_analysis_message.attr` is just
+ `hir_analysis::attr`).
+ - 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.
@@ -357,19 +368,32 @@ diagnostic struct.
- `maybe-incorrect`
- `has-placeholders`
- `unspecified`
-- `#[primary_span]` (_Mandatory_ for labels and suggestions; _optional_ otherwise)
+- `#[multipart_suggestion{,_hidden,_short,_verbose}(slug, applicability = "...")]`
+ - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
+ - _Mandatory_
+ - Defines the type to be representing a multipart suggestion.
+ - Slug (_Mandatory_): see `#[suggestion]`
+ - `applicability = "..."` (_Optional_): see `#[suggestion]`
+- `#[primary_span]` (_Mandatory_ for labels and suggestions; _optional_ otherwise; not applicable
+to multipart suggestions)
- _Applied to `Span` fields._
- Indicates the primary span of the subdiagnostic.
-- `#[applicability]` (_Optional_; only applicable to suggestions)
+- `#[suggestion_part(code = "...")]` (_Mandatory_; only applicable to multipart suggestions)
+ - _Applied to `Span` fields._
+ - Indicates the span to be one part of the multipart suggestion.
+ - `code = "..."` (_Mandatory_)
+ - Value is a format string indicating the code to be suggested as a
+ replacement.
+- `#[applicability]` (_Optional_; only applicable to (simple and multipart) suggestions)
- _Applied to `Applicability` fields._
- Indicates the applicability of the suggestion.
- `#[skip_arg]` (_Optional_)
- _Applied to any field._
- Prevents the field from being provided as a diagnostic argument.
-[defn]: https://github.com/rust-lang/rust/blob/bbe9d27b8ff36da56638aa43d6d0cdfdf89a4e57/compiler/rustc_typeck/src/errors.rs#L65-L74
-[use]: https://github.com/rust-lang/rust/blob/eb82facb1626166188d49599a3313fc95201f556/compiler/rustc_typeck/src/collect.rs#L981-L985
+[defn]: https://github.com/rust-lang/rust/blob/6201eabde85db854c1ebb57624be5ec699246b50/compiler/rustc_hir_analysis/src/errors.rs#L68-L77
+[use]: https://github.com/rust-lang/rust/blob/f1112099eba41abadb6f921df7edba70affe92c5/compiler/rustc_hir_analysis/src/collect.rs#L823-L827
-[subdiag_defn]: https://github.com/rust-lang/rust/blob/e70c60d34b9783a2fd3171d88d248c2e0ec8ecdd/compiler/rustc_typeck/src/errors.rs#L220-L233
-[subdiag_use_1]: https://github.com/rust-lang/rust/blob/e70c60d34b9783a2fd3171d88d248c2e0ec8ecdd/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs#L556-L560
-[subdiag_use_2]: https://github.com/rust-lang/rust/blob/e70c60d34b9783a2fd3171d88d248c2e0ec8ecdd/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs#L575-L579
+[subdiag_defn]: https://github.com/rust-lang/rust/blob/f1112099eba41abadb6f921df7edba70affe92c5/compiler/rustc_hir_analysis/src/errors.rs#L221-L234
+[subdiag_use_1]: https://github.com/rust-lang/rust/blob/f1112099eba41abadb6f921df7edba70affe92c5/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs#L670-L674
+[subdiag_use_2]: https://github.com/rust-lang/rust/blob/f1112099eba41abadb6f921df7edba70affe92c5/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs#L704-L707
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
index 39007f8d1..33d9646f6 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
@@ -1,4 +1,5 @@
# Lints
+
This page documents some of the machinery around lint registration and how we
run lints in the compiler.
@@ -8,6 +9,7 @@ everything rotates. It's not available during the early parts of compilation
lints, which can only happen after plugin registration.
## Lints vs. lint passes
+
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."
@@ -15,11 +17,18 @@ 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_session::lint::Lint`.
+[`&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,
+which boils down to a static with type [`&rustc_lint_defs::Lint`]
+(although this may change in the future,
+as the macro is somewhat unwieldy to add new fields to,
+like all macros).
-As of <!-- date: 2022-02 --> February 2022, we lint against direct declarations
-without the use of the macro today (although this may change in the future, as
-the macro is somewhat unwieldy to add new fields to, like all macros).
+As of <!-- date-check --> Aug 2022,
+we lint against direct declarations without the use of the macro.
Lint declarations don't carry any "state" - they are merely global identifiers
and descriptions of lints. We assert at runtime that they are not registered
@@ -34,8 +43,10 @@ lints are emitted as part of other work (e.g., type checking, etc.).
## Registration
### High-level overview
-In [`rustc_interface::register_plugins`] the [`LintStore`] is created and all
-lints are registered.
+
+In [`rustc_interface::register_plugins`],
+the [`LintStore`] is created,
+and all lints are registered.
There are four 'sources' of lints:
@@ -61,6 +72,7 @@ then invoke the lint pass methods. The lint pass methods take `&mut self` so
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`.
@@ -73,16 +85,20 @@ function which is called when constructing a new lint store inside
[`rustc_lint::new_lint_store`].
### Builtin Lints
-These are primarily described in two places: `rustc_session::lint::builtin` and
-`rustc_lint::builtin`. Often the first provides the definitions for the lints
-themselves, and the latter provides the lint pass definitions (and
-implementations), but this is not always true.
-The builtin lint registration happens in the [`rustc_lint::register_builtins`]
-function. Just like with internal lints, this happens inside of
-[`rustc_lint::new_lint_store`].
+These are primarily described in two places,
+`rustc_lint_defs::builtin` and `rustc_lint::builtin`.
+Often the first provides the definitions for the lints themselves,
+and the latter provides the lint pass definitions (and implementations),
+but this is not always true.
+
+The builtin lint registration happens in
+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
@@ -94,6 +110,7 @@ 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`
[`register_lints`] field, which is a callback. Drivers should, if finding it
already set, call the function currently set within the callback they add. The
@@ -102,6 +119,7 @@ best way for drivers to get access to this is by overriding the
structure.
## Compiler lint passes are combined into one pass
+
Within the compiler, for performance reasons, we usually do not register dozens
of lint passes. Instead, we have a single lint pass of each variety (e.g.,
`BuiltinCombinedModuleLateLintPass`) which will internally call all of the
@@ -121,3 +139,4 @@ approach, it is beneficial to do so for performance reasons.
[`declare_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/macro.declare_lint.html
[`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
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/translation.md b/src/doc/rustc-dev-guide/src/diagnostics/translation.md
index 5c078ffb3..e36333039 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/translation.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/translation.md
@@ -11,7 +11,7 @@ There are two ways of writing translatable diagnostics:
diagnostic structs). See [the diagnostic and subdiagnostic structs
documentation](./diagnostic-structs.md).
2. Using typed identifiers with `DiagnosticBuilder` APIs (in
- `SessionDiagnostic` implementations).
+ `Diagnostic` implementations).
When adding or changing a translatable diagnostic, you don't need to worry
about the translations, only updating the original English message. Currently,
@@ -32,23 +32,23 @@ Diagnostic messages are defined in Fluent resources. A combined set of Fluent
resources for a given locale (e.g. `en-US`) is known as Fluent bundle.
```fluent
-typeck-address-of-temporary-taken = cannot take address of a temporary
+typeck_address_of_temporary_taken = cannot take address of a temporary
```
-In the above example, `typeck-address-of-temporary-taken` is the identifier for
+In the above example, `typeck_address_of_temporary_taken` is the identifier for
a Fluent message and corresponds to the diagnostic message in English. Other
Fluent resources can be written which would correspond to a message in another
language. Each diagnostic therefore has at least one Fluent message.
```fluent
-typeck-address-of-temporary-taken = cannot take address of a temporary
+typeck_address_of_temporary_taken = cannot take address of a temporary
.label = temporary value
```
By convention, diagnostic messages for subdiagnostics are specified as
"attributes" on Fluent messages (additional related messages, denoted by the
`.<attribute-name>` syntax). In the above example, `label` is an attribute of
-`typeck-address-of-temporary-taken` which corresponds to the message for the
+`typeck_address_of_temporary_taken` which corresponds to the message for the
label added to this diagnostic.
Diagnostic messages often interpolate additional context into the message shown
@@ -56,7 +56,7 @@ to the user, such as the name of a type or of a variable. Additional context to
Fluent messages is provided as an "argument" to the diagnostic.
```fluent
-typeck-struct-expr-non-exhaustive =
+typeck_struct_expr_non_exhaustive =
cannot create non-exhaustive {$what} using struct expression
```
@@ -67,6 +67,13 @@ discussed in detail later).
You can consult the [Fluent] documentation for other usage examples of Fluent
and its syntax.
+### Guideline for message naming
+Usually, fluent uses `-` for separating words inside a message name. However,
+`_` is accepted by fluent as well. As `_` fits Rust's use cases better, due to
+the identifiers on the Rust side using `_` as well, inside rustc, `-` is not
+allowed for separating words, and instead `_` is recommended. The only exception
+is for leading `-`s, for message names like `-passes_see_issue`.
+
### Guidelines for writing translatable messages
For a message to be translatable into different languages, all of the
information required by any language must be provided to the diagnostic as an
@@ -106,10 +113,10 @@ fluent_messages! {
For example, given the following Fluent...
```fluent
-typeck-field-multiply-specified-in-initializer =
+typeck_field_multiply_specified_in_initializer =
field `{$ident}` specified more than once
.label = used more than once
- .label-previous-use = first use of `{$ident}`
+ .label_previous_use = first use of `{$ident}`
```
...then the `fluent_messages` macro will generate:
@@ -120,14 +127,12 @@ pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[
];
mod fluent_generated {
- mod typeck {
- pub const field_multiply_specified_in_initializer: DiagnosticMessage =
- DiagnosticMessage::new("typeck-field-multiply-specified-in-initializer");
- pub const label: SubdiagnosticMessage =
- SubdiagnosticMessage::attr("label");
- pub const label_previous_use: SubdiagnosticMessage =
- SubdiagnosticMessage::attr("previous-use-label");
- }
+ pub const typeck_field_multiply_specified_in_initializer: DiagnosticMessage =
+ DiagnosticMessage::new("typeck_field_multiply_specified_in_initializer");
+ pub const label: SubdiagnosticMessage =
+ SubdiagnosticMessage::attr("label");
+ pub const label_previous_use: SubdiagnosticMessage =
+ SubdiagnosticMessage::attr("previous_use_label");
}
```
@@ -136,9 +141,9 @@ mod fluent_generated {
```rust
use rustc_errors::fluent;
-let mut err = sess.struct_span_err(span, fluent::typeck::field_multiply_specified_in_initializer);
-err.span_label(span, fluent::typeck::label);
-err.span_label(previous_use_span, fluent::typeck::previous_use_label);
+let mut err = sess.struct_span_err(span, fluent::typeck_field_multiply_specified_in_initializer);
+err.span_label(span, fluent::label);
+err.span_label(previous_use_span, fluent::previous_use_label);
err.emit();
```
@@ -217,7 +222,7 @@ returned by `Emitter::fluent_bundle`. This bundle is used preferentially when
translating messages, the fallback bundle is only used if the primary bundle is
missing a message or not provided.
-As of <!-- date: 2022-06 --> June 2022, there are no locale bundles
+As of <!-- date-check --> June 2022, there are no locale bundles
distributed with the compiler, but mechanisms are implemented for loading
bundles.
diff --git a/src/doc/rustc-dev-guide/src/feature-gates.md b/src/doc/rustc-dev-guide/src/feature-gates.md
index 229281f2f..9e9a83ea6 100644
--- a/src/doc/rustc-dev-guide/src/feature-gates.md
+++ b/src/doc/rustc-dev-guide/src/feature-gates.md
@@ -9,7 +9,9 @@ modifying feature gates.
See ["Stability in code"] for help with adding a new feature; this section just
covers how to add the feature gate *declaration*.
-Add a feature gate declaration to `rustc_feature/src/active.rs` in the active
+First, add the feature name to `rustc_span/src/symbol.rs` in the `Symbols {...}` block.
+
+Then, add a feature gate declaration to `rustc_feature/src/active.rs` in the active
`declare_features` block:
```rust,ignore
diff --git a/src/doc/rustc-dev-guide/src/generics.md b/src/doc/rustc-dev-guide/src/generics.md
index 13549b2fb..0173bee8f 100644
--- a/src/doc/rustc-dev-guide/src/generics.md
+++ b/src/doc/rustc-dev-guide/src/generics.md
@@ -125,7 +125,7 @@ You may have a couple of followup questions…
`MyStruct`: `Adt(Foo, &[Param(0), Param(1)])`.
**`subst`** How do we actually do the substitutions? There is a function for that too! You use
-[`subst`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/subst/trait.Subst.html) to
+[`subst`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/subst/struct.EarlyBinder.html#method.subst) to
replace a `SubstRef` with another list of types.
[Here is an example of actually using `subst` in the compiler][substex]. The exact details are not
@@ -134,7 +134,7 @@ a real `ty::Ty`. You can see that we first get some substitutions (`substs`). T
`type_of` to get a type and call `ty.subst(substs)` to get a new version of `ty` with
the substitutions made.
-[substex]: https://github.com/rust-lang/rust/blob/597f432489f12a3f33419daa039ccef11a12c4fd/src/librustc_typeck/astconv.rs#L942-L953
+[substex]: https://github.com/rust-lang/rust/blob/0940040c0486a536be4f8685c7dd9a078f9e87c2/compiler/rustc_hir_analysis/src/astconv/mod.rs#L1231-L1242
**Note on indices:** It is possible for the indices in `Param` to not match with what we expect. For
example, the index could be out of bounds or it could be the index of a lifetime when we were
diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md
index f16c22d93..65397e349 100644
--- a/src/doc/rustc-dev-guide/src/git.md
+++ b/src/doc/rustc-dev-guide/src/git.md
@@ -148,8 +148,8 @@ Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
+ modified: src/llvm-project (new commits)
modified: src/tools/cargo (new commits)
- modified: src/tools/rls (new commits)
no changes added to commit (use "git add" and/or "git commit -a")
```
@@ -157,9 +157,12 @@ no changes added to commit (use "git add" and/or "git commit -a")
These changes are not changes to files: they are changes to submodules (more on
this [later](#git-submodules)). To get rid of those, run `git submodule update`
(or run any `x.py` command, which will automatically update the submodules).
-Note that there is (as of <!-- date: 2022-02 --> February 2022) a [bug][#77620] if you use
-worktrees, submodules, and `x.py` in a commit hook. If you run into an error
-like:
+Note that,
+as of <!-- date-check --> Aug 2022,
+there is a [bug][#77620] if you use worktrees,
+submodules, and `x.py` in a commit hook.
+If you run into an error like the following,
+it's not anything you did wrong:
```
error: failed to read `/home/joshua/rustc-worktree/src/tools/miri/cargo-miri/Cargo.toml`
@@ -167,11 +170,14 @@ error: failed to read `/home/joshua/rustc-worktree/src/tools/miri/cargo-miri/Car
Caused by:
No such file or directory (os error 2)
```
-it's not anything you did wrong. There is a workaround in [the issue][#77620-workaround].
+
+There is a workaround in [the issue][#77620-workaround].
[#77620]: https://github.com/rust-lang/rust/issues/77620
[#77620-workaround]: https://github.com/rust-lang/rust/issues/77620#issuecomment-705228229
+(Note that as of Sept 2022 `miri` is a subtree and not a submodule.)
+
## Rebasing and Conflicts
When you edit your code locally, you are making changes to the version of
@@ -387,41 +393,41 @@ you might want to get used to the main concepts of Git before reading this secti
The `rust-lang/rust` repository uses [Git submodules] as a way to use other
Rust projects from within the `rust` repo. Examples include Rust's fork of
-`llvm-project` and many devtools such as `cargo` and `rls`.
+`llvm-project`, `cargo` and libraries like `stdarch` and `backtrace`.
Those projects are developed and maintained in an separate Git (and GitHub)
repository, and they have their own Git history/commits, issue tracker and PRs.
Submodules allow us to create some sort of embedded sub-repository inside the
`rust` repository and use them like they were directories in the `rust` repository.
-Take `miri` for example. `miri` is maintained in the [`rust-lang/miri`] repository,
-but it is used in `rust-lang/rust` by the compiler for const evaluation. We bring it
-in `rust` as a submodule, in the `src/tools/miri` folder.
+Take `llvm-project` for example. `llvm-project` is maintained in the [`rust-lang/llvm-project`]
+repository, but it is used in `rust-lang/rust` by the compiler for code generation and
+optimization. We bring it in `rust` as a submodule, in the `src/llvm-project` folder.
The contents of submodules are ignored by Git: submodules are in some sense isolated
-from the rest of the repository. However, if you try to `cd src/tools/miri` and then
+from the rest of the repository. However, if you try to `cd src/llvm-project` and then
run `git status`:
```
-HEAD detached at 3fafb835
+HEAD detached at 9567f08afc943
nothing to commit, working tree clean
```
-As far as git is concerned, you are no longer in the `rust` repo, but in the `miri` repo.
+As far as git is concerned, you are no longer in the `rust` repo, but in the `llvm-project` repo.
You will notice that we are in "detached HEAD" state, i.e. not on a branch but on a
particular commit.
This is because, like any dependency, we want to be able to control which version to use.
Submodules allow us to do just that: every submodule is "pinned" to a certain
commit, which doesn't change unless modified manually. If you use `git checkout <commit>`
-in the `miri` directory and go back to the `rust` directory, you can stage this
-change like any other, e.g. by running `git add src/tools/miri`. (Note that if
+in the `llvm-project` directory and go back to the `rust` directory, you can stage this
+change like any other, e.g. by running `git add src/llvm-project`. (Note that if
you *don't* stage the change to commit, then you run the risk that running
`x.py` will just undo your change by switching back to the previous commit when
it automatically "updates" the submodules.)
This version selection is usually done by the maintainers of the project, and
-looks like [this][miri-update].
+looks like [this][llvm-update].
Git submodules take some time to get used to, so don't worry if it isn't perfectly
clear yet. You will rarely have to use them directly and, again, you don't need
@@ -430,6 +436,5 @@ exist and that they correspond to some sort of embedded subrepository dependency
that Git can nicely and fairly conveniently handle for us.
[Git submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules
-[`rust-toolstate`]: https://rust-lang-nursery.github.io/rust-toolstate/
-[`rust-lang/miri`]: https://github.com/rust-lang/miri
-[miri-update]: https://github.com/rust-lang/rust/pull/77500/files
+[`rust-lang/llvm-project`]: https://github.com/rust-lang/llvm-project
+[llvm-update]: https://github.com/rust-lang/rust/pull/99464/files
diff --git a/src/doc/rustc-dev-guide/src/img/rustc_stages.svg b/src/doc/rustc-dev-guide/src/img/rustc_stages.svg
deleted file mode 100644
index 25f7ab11b..000000000
--- a/src/doc/rustc-dev-guide/src/img/rustc_stages.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="581px" height="816px" viewBox="-0.5 -0.5 581 816"><defs/><g><rect x="0" y="0" width="580" height="315" fill="#ffffff" stroke="#000000" pointer-events="all"/><rect x="0" y="665" width="580" height="150" fill="#ffffff" stroke="#000000" pointer-events="all"/><rect x="0" y="345" width="580" height="287.5" fill="#ffffff" stroke="#000000" pointer-events="all"/><path d="M 120 25 L 193.63 25" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 198.88 25 L 191.88 28.5 L 193.63 25 L 191.88 21.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 25px; margin-left: 160px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Download</div></div></div></foreignObject><text x="160" y="28" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Download</text></switch></g><rect x="40" y="10" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 25px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">beta</div></div></div></foreignObject><text x="80" y="29" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">beta</text></switch></g><rect x="200" y="10" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 25px; margin-left: 201px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0</div></div></div></foreignObject><text x="240" y="29" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0</text></switch></g><path d="M 120 120 L 173.63 120" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 120 L 171.88 123.5 L 173.63 120 L 171.88 116.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 120px; margin-left: 144px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Builds</div></div></div></foreignObject><text x="144" y="123" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Builds</text></switch></g><rect x="40" y="105" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 120px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0</div></div></div></foreignObject><text x="80" y="124" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0</text></switch></g><path d="M 260 120 L 313.63 120" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 318.88 120 L 311.88 123.5 L 313.63 120 L 311.88 116.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 120px; margin-left: 290px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Outputs</div></div></div></foreignObject><text x="290" y="123" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Outputs</text></switch></g><rect x="180" y="105" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 120px; margin-left: 181px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">libtest/libstd</div></div></div></foreignObject><text x="220" y="124" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">libtest/libstd</text></switch></g><path d="M 400 120 L 453.63 120" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 458.88 120 L 451.88 123.5 L 453.63 120 L 451.88 116.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 120px; margin-left: 430px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Copy</div></div></div></foreignObject><text x="430" y="123" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Copy</text></switch></g><rect x="320" y="105" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 120px; margin-left: 321px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0-std</div></div></div></foreignObject><text x="360" y="124" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0-std</text></switch></g><path d="M 515 135 L 515 145 Q 515 155 505 155 L 230 155 Q 220 155 220 161.82 L 220 168.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 220 173.88 L 216.5 166.88 L 220 168.63 L 223.5 166.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="460" y="105" width="110" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 120px; margin-left: 461px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0-sysroot</div></div></div></foreignObject><text x="515" y="124" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0-sysroot</text></switch></g><path d="M 120 190 L 173.63 190" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 190 L 171.88 193.5 L 173.63 190 L 171.88 186.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 190px; margin-left: 144px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Builds</div></div></div></foreignObject><text x="144" y="193" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Builds</text></switch></g><rect x="40" y="175" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 190px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0</div></div></div></foreignObject><text x="80" y="194" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0</text></switch></g><path d="M 260 190 L 313.63 190" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 318.88 190 L 311.88 193.5 L 313.63 190 L 311.88 186.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 190px; margin-left: 290px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Outputs</div></div></div></foreignObject><text x="290" y="193" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Outputs</text></switch></g><rect x="180" y="175" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 190px; margin-left: 181px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">rustc</div></div></div></foreignObject><text x="220" y="194" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">rustc</text></switch></g><path d="M 400 190 L 453.63 190" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 458.88 190 L 451.88 193.5 L 453.63 190 L 451.88 186.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 190px; margin-left: 430px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Copy</div></div></div></foreignObject><text x="430" y="193" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Copy</text></switch></g><rect x="320" y="175" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 190px; margin-left: 321px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0-rustc</div></div></div></foreignObject><text x="360" y="194" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0-rustc</text></switch></g><path d="M 515 205 L 515 227.5 Q 515 237.5 505 237.5 L 230 237.5 Q 220 237.5 220 247.5 L 220 263.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 220 268.88 L 216.5 261.88 L 220 263.63 L 223.5 261.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="460" y="175" width="110" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 190px; margin-left: 461px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0-sysroot</div></div></div></foreignObject><text x="515" y="194" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0-sysroot</text></switch></g><path d="M 120 237.5 L 210 237.5 Q 220 237.5 220 247.5 L 220 263.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 220 268.88 L 216.5 261.88 L 220 263.63 L 223.5 261.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="40" y="222.5" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 238px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">llvm</div></div></div></foreignObject><text x="80" y="241" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">llvm</text></switch></g><path d="M 120 285 L 173.63 285" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 285 L 171.88 288.5 L 173.63 285 L 171.88 281.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 285px; margin-left: 144px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Builds</div></div></div></foreignObject><text x="144" y="288" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Builds</text></switch></g><rect x="40" y="270" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 285px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0</div></div></div></foreignObject><text x="80" y="289" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0</text></switch></g><path d="M 260 285 L 313.63 285" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 318.88 285 L 311.88 288.5 L 313.63 285 L 311.88 281.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 285px; margin-left: 290px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Outputs</div></div></div></foreignObject><text x="290" y="288" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Outputs</text></switch></g><rect x="180" y="270" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 285px; margin-left: 181px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">codegen</div></div></div></foreignObject><text x="220" y="289" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">codegen</text></switch></g><rect x="320" y="270" width="100" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 285px; margin-left: 321px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0-codegen</div></div></div></foreignObject><text x="370" y="289" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0-codegen</text></switch></g><rect x="-30" y="145" width="90" height="20" fill="none" stroke="none" transform="rotate(-90,15,155)" pointer-events="all"/><g transform="translate(-0.5 -0.5)rotate(-90 15 155)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 155px; margin-left: -29px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 24px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Stage 0</div></div></div></foreignObject><text x="15" y="162" fill="#000000" font-family="Helvetica" font-size="24px" text-anchor="middle">Stage 0</text></switch></g><path d="M 150 380 L 203.63 380" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 208.88 380 L 201.88 383.5 L 203.63 380 L 201.88 376.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 380px; margin-left: 174px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Copy</div></div></div></foreignObject><text x="174" y="383" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Copy</text></switch></g><rect x="40" y="355" width="110" height="50" rx="7.5" ry="7.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 380px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0-rustc<br />stage0-codegen<br />stage0-sysroot</div></div></div></foreignObject><text x="95" y="384" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0-rustc...</text></switch></g><path d="M 250 395 L 250 405 Q 250 415 240 415 L 90 415 Q 80 415 80 421.82 L 80 428.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 80 433.88 L 76.5 426.88 L 80 428.63 L 83.5 426.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="210" y="365" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 380px; margin-left: 211px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1</div></div></div></foreignObject><text x="250" y="384" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1</text></switch></g><path d="M 120 450 L 173.63 450" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 450 L 171.88 453.5 L 173.63 450 L 171.88 446.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 450px; margin-left: 144px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Builds</div></div></div></foreignObject><text x="144" y="453" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Builds</text></switch></g><rect x="40" y="435" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 450px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1</div></div></div></foreignObject><text x="80" y="454" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1</text></switch></g><path d="M 260 450 L 313.63 450" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 318.88 450 L 311.88 453.5 L 313.63 450 L 311.88 446.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 450px; margin-left: 290px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Outputs</div></div></div></foreignObject><text x="290" y="453" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Outputs</text></switch></g><rect x="180" y="435" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 450px; margin-left: 181px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">libtest/libstd</div></div></div></foreignObject><text x="220" y="454" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">libtest/libstd</text></switch></g><path d="M 400 450 L 453.63 450" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 458.88 450 L 451.88 453.5 L 453.63 450 L 451.88 446.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 450px; margin-left: 430px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Copy</div></div></div></foreignObject><text x="430" y="453" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Copy</text></switch></g><rect x="320" y="435" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 450px; margin-left: 321px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1-std</div></div></div></foreignObject><text x="360" y="454" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1-std</text></switch></g><path d="M 515 465 L 515 477.5 Q 515 487.5 505 487.5 L 230 487.5 Q 220 487.5 220 495.57 L 220 503.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 220 508.88 L 216.5 501.88 L 220 503.63 L 223.5 501.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="460" y="435" width="110" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 450px; margin-left: 461px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1/lib/rustlib</div></div></div></foreignObject><text x="515" y="454" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1/lib/rustlib</text></switch></g><path d="M 120 525 L 173.63 525" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 525 L 171.88 528.5 L 173.63 525 L 171.88 521.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 525px; margin-left: 144px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Builds</div></div></div></foreignObject><text x="144" y="528" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Builds</text></switch></g><rect x="40" y="510" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 525px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1</div></div></div></foreignObject><text x="80" y="529" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1</text></switch></g><path d="M 260 525 L 313.63 525" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 318.88 525 L 311.88 528.5 L 313.63 525 L 311.88 521.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 525px; margin-left: 290px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Outputs</div></div></div></foreignObject><text x="290" y="528" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Outputs</text></switch></g><rect x="180" y="510" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 525px; margin-left: 181px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">rustc</div></div></div></foreignObject><text x="220" y="529" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">rustc</text></switch></g><path d="M 400 525 L 453.63 525" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 458.88 525 L 451.88 528.5 L 453.63 525 L 451.88 521.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 525px; margin-left: 430px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Copy</div></div></div></foreignObject><text x="430" y="528" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Copy</text></switch></g><rect x="320" y="510" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 525px; margin-left: 321px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1-rustc</div></div></div></foreignObject><text x="360" y="529" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1-rustc</text></switch></g><path d="M 515 540 L 515 550 Q 515 560 505 560 L 230 560 Q 220 560 220 566.82 L 220 573.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 220 578.88 L 216.5 571.88 L 220 573.63 L 223.5 571.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="460" y="510" width="110" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 525px; margin-left: 461px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1/lib/rustlib</div></div></div></foreignObject><text x="515" y="529" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1/lib/rustlib</text></switch></g><path d="M 120 595 L 173.63 595" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 595 L 171.88 598.5 L 173.63 595 L 171.88 591.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 595px; margin-left: 144px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Builds</div></div></div></foreignObject><text x="144" y="598" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Builds</text></switch></g><rect x="40" y="580" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 595px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1</div></div></div></foreignObject><text x="80" y="599" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1</text></switch></g><path d="M 260 595 L 313.63 595" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 318.88 595 L 311.88 598.5 L 313.63 595 L 311.88 591.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 595px; margin-left: 290px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Outputs</div></div></div></foreignObject><text x="290" y="598" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Outputs</text></switch></g><rect x="180" y="580" width="80" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 595px; margin-left: 181px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">codegen</div></div></div></foreignObject><text x="220" y="599" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">codegen</text></switch></g><rect x="320" y="580" width="100" height="30" rx="4.5" ry="4.5" fill="#fff2cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 595px; margin-left: 321px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1-codegen</div></div></div></foreignObject><text x="370" y="599" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1-codegen</text></switch></g><rect x="-30" y="510" width="90" height="20" fill="none" stroke="none" transform="rotate(-90,15,520)" pointer-events="all"/><g transform="translate(-0.5 -0.5)rotate(-90 15 520)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 520px; margin-left: -29px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 24px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>Stage 1</div></div></div></div></foreignObject><text x="15" y="527" fill="#000000" font-family="Helvetica" font-size="24px" text-anchor="middle">Stage 1</text></switch></g><path d="M 150 702.5 L 203.63 702.5" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 208.88 702.5 L 201.88 706 L 203.63 702.5 L 201.88 699 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 703px; margin-left: 174px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Copy</div></div></div></foreignObject><text x="174" y="706" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Copy</text></switch></g><rect x="40" y="677.5" width="110" height="50" rx="7.5" ry="7.5" fill="#ccff99" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 108px; height: 1px; padding-top: 703px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage1-rustc<br />stage1-codegen<br />stage1/lib/rustlib</div></div></div></foreignObject><text x="95" y="706" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage1-rustc...</text></switch></g><path d="M 250 717.5 L 250 730 Q 250 740 240 740 L 90 740 Q 80 740 80 748.07 L 80 756.13" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 80 761.38 L 76.5 754.38 L 80 756.13 L 83.5 754.38 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="210" y="687.5" width="80" height="30" rx="4.5" ry="4.5" fill="#ccff99" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 703px; margin-left: 211px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage2</div></div></div></foreignObject><text x="250" y="706" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage2</text></switch></g><path d="M 120 777.5 L 173.63 777.5" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 777.5 L 171.88 781 L 173.63 777.5 L 171.88 774 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 778px; margin-left: 144px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Builds</div></div></div></foreignObject><text x="144" y="781" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Builds</text></switch></g><rect x="40" y="762.5" width="80" height="30" rx="4.5" ry="4.5" fill="#ccff99" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 778px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage2</div></div></div></foreignObject><text x="80" y="781" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage2</text></switch></g><path d="M 260 777.5 L 313.63 777.5" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 318.88 777.5 L 311.88 781 L 313.63 777.5 L 311.88 774 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 778px; margin-left: 290px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Outputs</div></div></div></foreignObject><text x="290" y="781" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Outputs</text></switch></g><rect x="180" y="762.5" width="80" height="30" rx="4.5" ry="4.5" fill="#ccff99" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 778px; margin-left: 181px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">rustdoc</div></div></div></foreignObject><text x="220" y="781" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">rustdoc</text></switch></g><path d="M 400 777.5 L 443.63 777.5" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 448.88 777.5 L 441.88 781 L 443.63 777.5 L 441.88 774 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 778px; margin-left: 425px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; "><div style="font-size: 11px">Copy</div></div></div></div></foreignObject><text x="425" y="781" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Copy</text></switch></g><rect x="320" y="762.5" width="80" height="30" rx="4.5" ry="4.5" fill="#ccff99" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 778px; margin-left: 321px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage2-tools</div></div></div></foreignObject><text x="360" y="781" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage2-tools</text></switch></g><path d="M 120 70 L 173.63 70" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 70 L 171.88 73.5 L 173.63 70 L 171.88 66.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 70px; margin-left: 144px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; background-color: #ffffff; white-space: nowrap; ">Builds</div></div></div></foreignObject><text x="144" y="73" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Builds</text></switch></g><rect x="40" y="55" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 70px; margin-left: 41px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage0</div></div></div></foreignObject><text x="80" y="74" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage0</text></switch></g><rect x="180" y="55" width="80" height="30" rx="4.5" ry="4.5" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 70px; margin-left: 181px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">bootstrap</div></div></div></foreignObject><text x="220" y="74" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">bootstrap</text></switch></g><path d="M 190 560 L 130 560 Q 120 560 120 558.75 L 120 558.13 Q 120 557.5 130 557.5 L 210 557.5 Q 220 557.5 220 564.32 L 220 571.13" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 220 576.38 L 216.5 569.38 L 220 571.13 L 223.5 569.38 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="110" y="551" width="80" height="18" rx="2.7" ry="2.7" fill="#ffe6cc" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 560px; margin-left: 111px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">llvm</div></div></div></foreignObject><text x="150" y="564" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">llvm</text></switch></g><rect x="450" y="762.5" width="80" height="30" rx="4.5" ry="4.5" fill="#ccff99" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 778px; margin-left: 451px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">stage2</div></div></div></foreignObject><text x="490" y="781" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">stage2</text></switch></g><rect x="-30" y="735" width="90" height="20" fill="none" stroke="none" transform="rotate(-90,15,745)" pointer-events="all"/><g transform="translate(-0.5 -0.5)rotate(-90 15 745)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 745px; margin-left: -29px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 24px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>Stage 2</div></div></div></div></foreignObject><text x="15" y="752" fill="#000000" font-family="Helvetica" font-size="24px" text-anchor="middle">Stage 2</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://desk.draw.io/support/solutions/articles/16000042487" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg> \ No newline at end of file
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 ef6ae6179..9147c1b41 100644
--- a/src/doc/rustc-dev-guide/src/implementing_new_features.md
+++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md
@@ -28,6 +28,12 @@ get by with only an r+. For example, it is OK to add or modify
unstable command-line flags or attributes without an FCP for
compiler development or standard library use, as long as you don't
expect them to be in wide use in the nightly ecosystem.
+Some teams have lighter weight processes that they use in scenarios
+like this; for example, the compiler team recommends
+filing a Major Change Proposal ([MCP][mcp]) as a lightweight way to
+garner support and feedback without requiring full consensus.
+
+[mcp]: compiler/mcp.md#public-facing-changes-require-rfcbot-fcp
You don't need to have the implementation fully ready for r+ to propose an FCP,
but it is generally a good idea to have at least a proof
@@ -123,9 +129,9 @@ a new unstable feature:
2. Pick a name for the feature gate (for RFCs, use the name
in the RFC).
-3. Add a feature gate declaration to `rustc_feature/src/active.rs`
- in the active `declare_features` block. See [here][add-feature-gate] for
- detailed instructions.
+3. Add a feature gate declaration to `rustc_feature/src/active.rs` in the active
+ `declare_features` block, and add the feature gate keyword to
+ `rustc_span/src/symbol.rs`. See [here][add-feature-gate] for detailed instructions.
4. Prevent usage of the new feature unless the feature gate is set.
You can check it in most places in the compiler using the
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 ea4bdfca6..b186f4820 100644
--- a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
+++ b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md
@@ -222,9 +222,10 @@ properly-configured variables in LLVM IR, according to very specific
details of the [_LLVM Coverage Mapping Format_][coverage-mapping-format]
(Version 6).[^llvm-and-covmap-versions]
-[^llvm-and-covmap-versions]: The Rust compiler (as of <!-- date: 2021-12 -->
-December 2021) supports _LLVM Coverage Mapping Format_ Version 5 or 6. Version 5
-was introduced in _LLVM 12_, which is (as of this writing) the minimum LLVM
+[^llvm-and-covmap-versions]: The Rust compiler (as of <!-- date-check --> December 2021)
+supports _LLVM Coverage Mapping Format_ Version 5 or 6. Version 5
+was introduced in _LLVM 12_,
+which is (as of <!-- date-check: December 2021--> this writing) the minimum LLVM
version supported by the current version of Rust. Version 6 was introduced in
_LLVM 13_, which is currently the default LLVM version for Rust. The Rust
compiler will automatically use the most up-to-date coverage mapping format
diff --git a/src/doc/rustc-dev-guide/src/method-lookup.md b/src/doc/rustc-dev-guide/src/method-lookup.md
index 8eb8ec5ce..8b49e8d00 100644
--- a/src/doc/rustc-dev-guide/src/method-lookup.md
+++ b/src/doc/rustc-dev-guide/src/method-lookup.md
@@ -32,8 +32,8 @@ inference variables or other information.
[fully-qualified syntax]: https://doc.rust-lang.org/nightly/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name
[UFCS]: https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md
-[probe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/method/probe/
-[confirm]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/method/confirm/
+[probe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/method/probe/
+[confirm]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/method/confirm/
## The Probe phase
diff --git a/src/doc/rustc-dev-guide/src/miri.md b/src/doc/rustc-dev-guide/src/miri.md
deleted file mode 100644
index c5de358d2..000000000
--- a/src/doc/rustc-dev-guide/src/miri.md
+++ /dev/null
@@ -1,239 +0,0 @@
-# Miri
-
-<!-- toc -->
-
-The Miri (**MIR** **I**nterpreter) engine is a virtual machine for executing MIR without
-compiling to machine code. It is usually invoked via `tcx.const_eval_*` functions.
-In the following, we will refer to the Miri engine as just "Miri", but note that
-there also is a stand-alone
-[tool called "Miri"](https://github.com/rust-lang/miri/) that is based on the
-engine (sometimes referred to as Miri-the-tool to disambiguate it from the
-engine).
-
-If you start out with a constant:
-
-```rust
-const FOO: usize = 1 << 12;
-```
-
-rustc doesn't actually invoke anything until the constant is either used or
-placed into metadata.
-
-Once you have a use-site like:
-
-```rust,ignore
-type Foo = [u8; FOO - 42];
-```
-
-The compiler needs to figure out the length of the array before being able to
-create items that use the type (locals, constants, function arguments, ...).
-
-To obtain the (in this case empty) parameter environment, one can call
-`let param_env = tcx.param_env(length_def_id);`. The `GlobalId` needed is
-
-```rust,ignore
-let gid = GlobalId {
- promoted: None,
- instance: Instance::mono(length_def_id),
-};
-```
-
-Invoking `tcx.const_eval(param_env.and(gid))` will now trigger the creation of
-the MIR of the array length expression. The MIR will look something like this:
-
-```mir
-Foo::{{constant}}#0: usize = {
- let mut _0: usize;
- let mut _1: (usize, bool);
-
- bb0: {
- _1 = CheckedSub(const FOO, const 42usize);
- assert(!move (_1.1: bool), "attempt to subtract with overflow") -> bb1;
- }
-
- bb1: {
- _0 = move (_1.0: usize);
- return;
- }
-}
-```
-
-Before the evaluation, a virtual memory location (in this case essentially a
-`vec![u8; 4]` or `vec![u8; 8]`) is created for storing the evaluation result.
-
-At the start of the evaluation, `_0` and `_1` are
-`Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef))`. This is quite
-a mouthful: [`Operand`] can represent either data stored somewhere in the
-[interpreter memory](#memory) (`Operand::Indirect`), or (as an optimization)
-immediate data stored in-line. And [`Immediate`] can either be a single
-(potentially uninitialized) [scalar value][`Scalar`] (integer or thin pointer),
-or a pair of two of them. In our case, the single scalar value is *not* (yet)
-initialized.
-
-When the initialization of `_1` is invoked, the value of the `FOO` constant is
-required, and triggers another call to `tcx.const_eval_*`, which will not be shown
-here. If the evaluation of FOO is successful, `42` will be subtracted from its
-value `4096` and the result stored in `_1` as
-`Operand::Immediate(Immediate::ScalarPair(Scalar::Raw { data: 4054, .. },
-Scalar::Raw { data: 0, .. })`. The first part of the pair is the computed value,
-the second part is a bool that's true if an overflow happened. A `Scalar::Raw`
-also stores the size (in bytes) of this scalar value; we are eliding that here.
-
-The next statement asserts that said boolean is `0`. In case the assertion
-fails, its error message is used for reporting a compile-time error.
-
-Since it does not fail, `Operand::Immediate(Immediate::Scalar(Scalar::Raw {
-data: 4054, .. }))` is stored in the virtual memory was allocated before the
-evaluation. `_0` always refers to that location directly.
-
-After the evaluation is done, the return value is converted from [`Operand`] to
-[`ConstValue`] by [`op_to_const`]: the former representation is geared towards
-what is needed *during* const evaluation, while [`ConstValue`] is shaped by the
-needs of the remaining parts of the compiler that consume the results of const
-evaluation. As part of this conversion, for types with scalar values, even if
-the resulting [`Operand`] is `Indirect`, it will return an immediate
-`ConstValue::Scalar(computed_value)` (instead of the usual `ConstValue::ByRef`).
-This makes using the result much more efficient and also more convenient, as no
-further queries need to be executed in order to get at something as simple as a
-`usize`.
-
-Future evaluations of the same constants will not actually invoke
-Miri, but just use the cached result.
-
-[`Operand`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/interpret/enum.Operand.html
-[`Immediate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/interpret/enum.Immediate.html
-[`ConstValue`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/enum.ConstValue.html
-[`Scalar`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/enum.Scalar.html
-[`op_to_const`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/const_eval/eval_queries/fn.op_to_const.html
-
-## Datastructures
-
-Miri's outside-facing datastructures can be found in
-[rustc_middle/src/mir/interpret](https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/mir/interpret).
-This is mainly the error enum and the [`ConstValue`] and [`Scalar`] types. A
-`ConstValue` can be either `Scalar` (a single `Scalar`, i.e., integer or thin
-pointer), `Slice` (to represent byte slices and strings, as needed for pattern
-matching) or `ByRef`, which is used for anything else and refers to a virtual
-allocation. These allocations can be accessed via the methods on
-`tcx.interpret_interner`. A `Scalar` is either some `Raw` integer or a pointer;
-see [the next section](#memory) for more on that.
-
-If you are expecting a numeric result, you can use `eval_usize` (panics on
-anything that can't be represented as a `u64`) or `try_eval_usize` which results
-in an `Option<u64>` yielding the `Scalar` if possible.
-
-## Memory
-
-To support any kind of pointers, Miri needs to have a "virtual memory" that the
-pointers can point to. This is implemented in the [`Memory`] type. In the
-simplest model, every global variable, stack variable and every dynamic
-allocation corresponds to an [`Allocation`] in that memory. (Actually using an
-allocation for every MIR stack variable would be very inefficient; that's why we
-have `Operand::Immediate` for stack variables that are both small and never have
-their address taken. But that is purely an optimization.)
-
-Such an `Allocation` is basically just a sequence of `u8` storing the value of
-each byte in this allocation. (Plus some extra data, see below.) Every
-`Allocation` has a globally unique `AllocId` assigned in `Memory`. With that, a
-[`Pointer`] consists of a pair of an `AllocId` (indicating the allocation) and
-an offset into the allocation (indicating which byte of the allocation the
-pointer points to). It may seem odd that a `Pointer` is not just an integer
-address, but remember that during const evaluation, we cannot know at which
-actual integer address the allocation will end up -- so we use `AllocId` as
-symbolic base addresses, which means we need a separate offset. (As an aside,
-it turns out that pointers at run-time are
-[more than just integers, too](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#pointer-provenance).)
-
-These allocations exist so that references and raw pointers have something to
-point to. There is no global linear heap in which things are allocated, but each
-allocation (be it for a local variable, a static or a (future) heap allocation)
-gets its own little memory with exactly the required size. So if you have a
-pointer to an allocation for a local variable `a`, there is no possible (no
-matter how unsafe) operation that you can do that would ever change said pointer
-to a pointer to a different local variable `b`.
-Pointer arithmetic on `a` will only ever change its offset; the `AllocId` stays the same.
-
-This, however, causes a problem when we want to store a `Pointer` into an
-`Allocation`: we cannot turn it into a sequence of `u8` of the right length!
-`AllocId` and offset together are twice as big as a pointer "seems" to be. This
-is what the `relocation` field of `Allocation` is for: the byte offset of the
-`Pointer` gets stored as a bunch of `u8`, while its `AllocId` gets stored
-out-of-band. The two are reassembled when the `Pointer` is read from memory.
-The other bit of extra data an `Allocation` needs is `undef_mask` for keeping
-track of which of its bytes are initialized.
-
-### Global memory and exotic allocations
-
-`Memory` exists only during the Miri evaluation; it gets destroyed when the
-final value of the constant is computed. In case that constant contains any
-pointers, those get "interned" and moved to a global "const eval memory" that is
-part of `TyCtxt`. These allocations stay around for the remaining computation
-and get serialized into the final output (so that dependent crates can use
-them).
-
-Moreover, to also support function pointers, the global memory in `TyCtxt` can
-also contain "virtual allocations": instead of an `Allocation`, these contain an
-`Instance`. That allows a `Pointer` to point to either normal data or a
-function, which is needed to be able to evaluate casts from function pointers to
-raw pointers.
-
-Finally, the [`GlobalAlloc`] type used in the global memory also contains a
-variant `Static` that points to a particular `const` or `static` item. This is
-needed to support circular statics, where we need to have a `Pointer` to a
-`static` for which we cannot yet have an `Allocation` as we do not know the
-bytes of its value.
-
-[`Memory`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/interpret/struct.Memory.html
-[`Allocation`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/struct.Allocation.html
-[`Pointer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/struct.Pointer.html
-[`GlobalAlloc`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/enum.GlobalAlloc.html
-
-### Pointer values vs Pointer types
-
-One common cause of confusion in Miri is that being a pointer *value* and having
-a pointer *type* are entirely independent properties. By "pointer value", we
-refer to a `Scalar::Ptr` containing a `Pointer` and thus pointing somewhere into
-Miri's virtual memory. This is in contrast to `Scalar::Raw`, which is just some
-concrete integer.
-
-However, a variable of pointer or reference *type*, such as `*const T` or `&T`,
-does not have to have a pointer *value*: it could be obtained by casting or
-transmuting an integer to a pointer.
-And similarly, when casting or transmuting a reference to some
-actual allocation to an integer, we end up with a pointer *value*
-(`Scalar::Ptr`) at integer *type* (`usize`). This is a problem because we
-cannot meaningfully perform integer operations such as division on pointer
-values.
-
-## Interpretation
-
-Although the main entry point to constant evaluation is the `tcx.const_eval_*`
-functions, there are additional functions in
-[rustc_const_eval/src/const_eval](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/index.html)
-that allow accessing the fields of a `ConstValue` (`ByRef` or otherwise). You should
-never have to access an `Allocation` directly except for translating it to the
-compilation target (at the moment just LLVM).
-
-Miri starts by creating a virtual stack frame for the current constant that is
-being evaluated. There's essentially no difference between a constant and a
-function with no arguments, except that constants do not allow local (named)
-variables at the time of writing this guide.
-
-A stack frame is defined by the `Frame` type in
-[rustc_const_eval/src/interpret/eval_context.rs](https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/eval_context.rs)
-and contains all the local
-variables memory (`None` at the start of evaluation). Each frame refers to the
-evaluation of either the root constant or subsequent calls to `const fn`. The
-evaluation of another constant simply calls `tcx.const_eval_*`, which produce an
-entirely new and independent stack frame.
-
-The frames are just a `Vec<Frame>`, there's no way to actually refer to a
-`Frame`'s memory even if horrible shenanigans are done via unsafe code. The only
-memory that can be referred to are `Allocation`s.
-
-Miri now calls the `step` method (in
-[rustc_const_eval/src/interpret/step.rs](https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/step.rs)
-) until it either returns an error or has no further statements to execute. Each
-statement will now initialize or modify the locals or the virtual memory
-referred to by a local. This might require evaluating other constants or
-statics, which just recursively invokes `tcx.const_eval_*`.
diff --git a/src/doc/rustc-dev-guide/src/name-resolution.md b/src/doc/rustc-dev-guide/src/name-resolution.md
index c4f44909b..1dbc95ead 100644
--- a/src/doc/rustc-dev-guide/src/name-resolution.md
+++ b/src/doc/rustc-dev-guide/src/name-resolution.md
@@ -174,7 +174,7 @@ Still, it probably provides useful first guidepost to what happens in there.
following stages of compilation?
* Who calls it and how it is actually used.
* Is it a pass and then the result is only used, or can it be computed
- incrementally (e.g. for RLS)?
+ incrementally?
* The overall strategy description is a bit vague.
* Where does the name `Rib` come from?
* Does this thing have its own tests, or is it tested only as part of some e2e
diff --git a/src/doc/rustc-dev-guide/src/opaque-types-impl-trait-inference.md b/src/doc/rustc-dev-guide/src/opaque-types-impl-trait-inference.md
index 52d2127bf..f9c2ea74d 100644
--- a/src/doc/rustc-dev-guide/src/opaque-types-impl-trait-inference.md
+++ b/src/doc/rustc-dev-guide/src/opaque-types-impl-trait-inference.md
@@ -147,7 +147,7 @@ flowchart TD
### Relating an opaque type to another type
-There is one central place where an opaqe type gets its hidden type constrained,
+There is one central place where an opaque type gets its hidden type constrained,
and that is the `handle_opaque_type` function.
Amusingly it takes two types, so you can pass any two types,
but one of them should be an opaque type.
@@ -216,7 +216,7 @@ and then handle it correctly.
The MIR borrow checker relates things via `nll_relate` and only cares about regions.
Any type relation will trigger the binding of hidden types,
so the borrow checker is doing the same thing as the type checker,
-but ignores obivously dead code (e.g. after a panic).
+but ignores obviously dead code (e.g. after a panic).
The borrow checker is also the source of truth when it comes to hidden types,
as it is the only one who can properly figure out what lifetimes on the hidden type correspond
to which lifetimes on the opaque type declaration.
@@ -224,7 +224,7 @@ to which lifetimes on the opaque type declaration.
## Backwards compatibility hacks
`impl Trait` in return position has various quirks that were not part
-of any RFCs and are likely accidental stabilizations.
+of any RFCs and are likely accidental stabilization.
To support these,
the `replace_opaque_types_with_inference_vars` is being used to reintroduce the previous behaviour.
diff --git a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md
index 2be072dd2..956f56828 100644
--- a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md
+++ b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md
@@ -14,9 +14,9 @@ This declares an opaque type named `Foo`, of which the only information is that
it implements `Bar`. Therefore, any of `Bar`'s interface can be used on a `Foo`,
but nothing else (regardless of whether it implements any other traits).
-Since there needs to be a concrete background type, you can (as of <!-- date:
-2021-01 --> January 2021) express that type by using the opaque type in a
-"defining use site".
+Since there needs to be a concrete background type,
+you can (as of <!-- date-check --> January 2021) express that type
+by using the opaque type in a "defining use site".
```rust,ignore
struct Struct;
diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md
index de6c88e7e..7fbdfd359 100644
--- a/src/doc/rustc-dev-guide/src/overview.md
+++ b/src/doc/rustc-dev-guide/src/overview.md
@@ -177,7 +177,7 @@ satisfy/optimize for. For example,
of space on the user's system...
- Compiler memory usage: while compiling a program, we don't want to use more
memory than we need.
-- Program speed: how fast is your compiled program. More/better compile-time
+- Program speed: how fast is your compiled program? More/better compile-time
analyses often means the compiler can do better optimizations.
- Program size: how large is the compiled binary? Similar to the previous
point.
@@ -190,7 +190,7 @@ satisfy/optimize for. For example,
the input programs says they do, and should continue to do so despite the
tremendous amount of change constantly going on.
- Integration: a number of other tools need to use the compiler in
- various ways (e.g. cargo, clippy, miri, RLS) that must be supported.
+ various ways (e.g. cargo, clippy, miri) that must be supported.
- Compiler stability: the compiler should not crash or fail ungracefully on the
stable channel.
- Rust stability: the compiler must respect Rust's stability guarantees by not
@@ -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: 2021-11 --> November 2021, only the steps between HIR and
+but as of <!-- date-check --> November 2021, 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/panic-implementation.md b/src/doc/rustc-dev-guide/src/panic-implementation.md
index 66e61548e..d1ca202dc 100644
--- a/src/doc/rustc-dev-guide/src/panic-implementation.md
+++ b/src/doc/rustc-dev-guide/src/panic-implementation.md
@@ -28,7 +28,7 @@ Actually resolving this goes through several layers of indirection:
1. In `compiler/rustc_middle/src/middle/weak_lang_items.rs`, `panic_impl` is
declared as 'weak lang item', with the symbol `rust_begin_unwind`. This is
- used in `rustc_typeck/src/collect.rs` to set the actual symbol name to
+ used in `rustc_hir_analysis/src/collect.rs` to set the actual symbol name to
`rust_begin_unwind`.
Note that `panic_impl` is declared in an `extern "Rust"` block,
diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md
index 4aa13d781..e93f51dbb 100644
--- a/src/doc/rustc-dev-guide/src/parallel-rustc.md
+++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md
@@ -1,34 +1,116 @@
# Parallel Compilation
-As of <!-- date: 2022-05 --> May 2022, The only stage of the compiler
-that is already parallel is codegen. The nightly compiler implements query evaluation,
-but there is still a lot of work to be done. The lack of parallelism at other stages
-also represents an opportunity for improving compiler performance. One can try out the current
-parallel compiler work by enabling it in the `config.toml`.
+As of <!-- date-check --> August 2022, the only stage of the compiler that
+is already parallel is codegen. Some parts of the compiler already have
+parallel implementations, such as query evaluation, type check and
+monomorphization, but the general version of the compiler does not include
+these parallelization functions. **To try out the current parallel compiler**,
+one can install rustc from source code with `parallel-compiler = true` in
+the `config.toml`.
+
+The lack of parallelism at other stages (for example, macro expansion) also
+represents an opportunity for improving compiler performance.
These next few sections describe where and how parallelism is currently used,
and the current status of making parallel compilation the default in `rustc`.
-The underlying thread-safe data-structures used in the parallel compiler
-can be found in the `rustc_data_structures::sync` module. Some of these data structures
-use the `parking_lot` crate as well.
-
## Codegen
-There are two underlying thread safe data structures used in code generation:
-
-- `Lrc`
- - Which is an [`Arc`][Arc] if `parallel_compiler` is true, and a [`Rc`][Rc]
- if it is not.
-- `MetadataRef` -> [`OwningRef<Box<dyn Erased + Send + Sync>, [u8]>`][OwningRef]
- - This data structure is specific to `rustc`.
-
During [monomorphization][monomorphization] the compiler splits up all the code to
be generated into smaller chunks called _codegen units_. These are then generated by
independent instances of LLVM running in parallel. At the end, the linker
is run to combine all the codegen units together into one binary. This process
occurs in the `rustc_codegen_ssa::base` module.
+## Data Structures
+
+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.
+
+| data structure | parallel | non-parallel |
+| -------------------------------- | --------------------------------------------------- | ------------ |
+| Lrc | std::sync::Arc | std::rc::Rc |
+| Weak | std::sync::Weak | std::rc::Weak |
+| Atomic{Bool}/{Usize}/{U32}/{U64} | std::sync::atomic::Atomic{Bool}/{Usize}/{U32}/{U64} | (std::cell::Cell<bool/usize/u32/u64>) |
+| OnceCell | std::sync::OnceLock | std::cell::OnceCell |
+| Lock\<T> | (parking_lot::Mutex\<T>) | (std::cell::RefCell) |
+| RwLock\<T> | (parking_lot::RwLock\<T>) | (std::cell::RefCell) |
+| MTRef<'a, T> | &'a T | &'a mut T |
+| MTLock\<T> | (Lock\<T>) | (T) |
+| ReadGuard | parking_lot::RwLockReadGuard | std::cell::Ref |
+| MappedReadGuard | parking_lot::MappedRwLockReadGuard | std::cell::Ref |
+| WriteGuard | parking_lot::RwLockWriteGuard | std::cell::RefMut |
+| MappedWriteGuard | parking_lot::MappedRwLockWriteGuard | std::cell::RefMut |
+| LockGuard | parking_lot::MutexGuard | std::cell::RefMut |
+| MappedLockGuard | parking_lot::MappedMutexGuard | std::cell::RefMut |
+| MetadataRef | [`OwningRef<Box<dyn Erased + Send + Sync>, [u8]>`][OwningRef] | [`OwningRef<Box<dyn Erased>, [u8]>`][OwningRef] |
+
+- These thread-safe data structures interspersed during compilation can
+ cause a lot of lock contention, which actually degrades performance as the
+ number of threads increases beyond 4. This inspires us to audit the use
+ of these data structures, leading to either refactoring to reduce use of
+ shared state, or persistent documentation covering invariants, atomicity,
+ and lock orderings.
+
+- On the other hand, we still need to figure out what other invariants
+ during compilation might not hold in parallel compilation.
+
+### WorkLocal
+
+`WorkLocal` is a special data structure implemented for parallel compiler.
+It holds worker-locals values for each thread in a thread pool. You can only
+access the worker local value through the Deref impl on the thread pool it
+was constructed on. It will panic otherwise.
+
+`WorkLocal` is used to implement the `Arena` allocator in the parallel
+environment, which is critical in parallel queries. Its implementation
+is located in the `rustc-rayon-core::worker_local` module. However, in the
+non-parallel compiler, it is implemented as `(OneThread<T>)`, whose `T`
+can be accessed directly through `Deref::deref`.
+
+## Parallel Iterator
+
+The parallel iterators provided by the [`rayon`] crate are easy ways
+to implement parallelism. In the current implementation of the parallel
+compiler we use a custom [fork][rustc-rayon] of [`rayon`] to run tasks in parallel.
+
+Some iterator functions are implemented to run loops in parallel
+when `parallel-compiler` is true.
+
+| Function(Omit `Send` and `Sync`) | Introduction | Owning Module |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------------- |
+| **par_iter**<T: IntoParallelIterator>(t: T) -> T::Iter | generate a parallel iterator | rustc_data_structure::sync |
+| **par_for_each_in**<T: IntoParallelIterator>(t: T, for_each: impl Fn(T::Item)) | generate a parallel iterator and run `for_each` on each element | rustc_data_structure::sync |
+| **Map::par_body_owners**(self, f: impl Fn(LocalDefId)) | run `f` on all hir owners in the crate | rustc_middle::hir::map |
+| **Map::par_for_each_module**(self, f: impl Fn(LocalDefId)) | run `f` on all modules and sub modules in the crate | rustc_middle::hir::map |
+| **ModuleItems::par_items**(&self, f: impl Fn(ItemId)) | run `f` on all items in the module | rustc_middle::hir |
+| **ModuleItems::par_trait_items**(&self, f: impl Fn(TraitItemId)) | run `f` on all trait items in the module | rustc_middle::hir |
+| **ModuleItems::par_impl_items**(&self, f: impl Fn(ImplItemId)) | run `f` on all impl items in the module | rustc_middle::hir |
+| **ModuleItems::par_foreign_items**(&self, f: impl Fn(ForeignItemId)) | run `f` on all foreign items in the module | rustc_middle::hir |
+
+There are a lot of loops in the compiler which can possibly be
+parallelized using these functions. As of <!-- date-check--> August
+2022, scenarios where the parallel iterator function has been used
+are as follows:
+
+| caller | scenario | callee |
+| ------------------------------------------------------- | ------------------------------------------------------------ | ------------------------ |
+| rustc_metadata::rmeta::encoder::prefetch_mir | Prefetch queries which will be needed later by metadata encoding | par_iter |
+| rustc_monomorphize::collector::collect_crate_mono_items | Collect monomorphized items reachable from non-generic items | par_for_each_in |
+| rustc_interface::passes::analysis | Check the validity of the match statements | Map::par_body_owners |
+| rustc_interface::passes::analysis | MIR borrow check | Map::par_body_owners |
+| rustc_typeck::check::typeck_item_bodies | Type check | Map::par_body_owners |
+| rustc_interface::passes::hir_id_validator::check_crate | Check the validity of hir | Map::par_for_each_module |
+| rustc_interface::passes::analysis | Check the validity of loops body, attributes, naked functions, unstable abi, const bodys | Map::par_for_each_module |
+| rustc_interface::passes::analysis | Liveness and intrinsic checking of MIR | Map::par_for_each_module |
+| rustc_interface::passes::analysis | Deathness checking | Map::par_for_each_module |
+| rustc_interface::passes::analysis | Privacy checking | Map::par_for_each_module |
+| rustc_lint::late::check_crate | Run per-module lints | Map::par_for_each_module |
+| rustc_typeck::check_crate | Well-formedness checking | Map::par_for_each_module |
+
+There are still many loops that have the potential to use parallel iterators.
+
## Query System
The query model has some properties that make it actually feasible to evaluate
@@ -48,44 +130,22 @@ When a query `foo` is evaluated, the cache table for `foo` is locked.
start evaluating.
- If there *is* another query invocation for the same key in progress, we
release the lock, and just block the thread until the other invocation has
- computed the result we are waiting for. This cannot deadlock because, as
- mentioned before, query invocations form a DAG. Some threads will always make
- progress.
+ computed the result we are waiting for. **Cycle error detection** in the parallel
+ compiler requires more complex logic than in single-threaded mode. When
+ worker threads in parallel queries stop making progress due to interdependence,
+ the compiler uses an extra thread *(named deadlock handler)* to detect, remove and
+ report the cycle error.
+
+Parallel query still has a lot of work to do, most of which is related to
+the previous `Data Structures` and `Parallel Iterators`. See [this tracking issue][tracking].
## Rustdoc
-As of <!-- date: 2022-05--> May 2022, there are still a number of steps
+As of <!-- date-check--> May 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].
-## Current Status
-
-As of <!-- date: 2022-05 --> May 2022, work on explicitly parallelizing the
-compiler has stalled. There is a lot of design and correctness work that needs
-to be done.
-
-These are the basic ideas in the effort to make `rustc` parallel:
-
-- There are a lot of loops in the compiler that just iterate over all items in
- a crate. These can possibly be parallelized.
-- We can use (a custom fork of) [`rayon`] to run tasks in parallel. The custom
- fork allows the execution of DAGs of tasks, not just trees.
-- There are currently a lot of global data structures that need to be made
- thread-safe. A key strategy here has been converting interior-mutable
- data-structures (e.g. `Cell`) into their thread-safe siblings (e.g. `Mutex`).
-
-[`rayon`]: https://crates.io/crates/rayon
-
-As of <!-- date: 2022-05 --> May 2022, much of this effort is on hold due
-to lack of manpower. We have a working prototype with promising performance
-gains in many cases. However, there are two blockers:
-
-- It's not clear what invariants need to be upheld that might not hold in the
- face of concurrency. An auditing effort was underway, but seems to have
- stalled at some point.
-
-- There is a lot of lock contention, which actually degrades performance as the
- number of threads increases beyond 4.
+## Resources
Here are some resources that can be used to learn more (note that some of them
are a bit out of date):
@@ -93,8 +153,9 @@ are a bit out of date):
- [This IRLO thread by Zoxc, one of the pioneers of the effort][irlo0]
- [This list of interior mutability in the compiler by nikomatsakis][imlist]
- [This IRLO thread by alexchricton about performance][irlo1]
-- [This tracking issue][tracking]
+[`rayon`]: https://crates.io/crates/rayon
+[rustc-rayon]: https://github.com/rust-lang/rustc-rayon
[irlo0]: https://internals.rust-lang.org/t/parallelizing-rustc-using-rayon/6606
[imlist]: https://github.com/nikomatsakis/rustc-parallelization/blob/master/interior-mutability-list.md
[irlo1]: https://internals.rust-lang.org/t/help-test-parallel-rustc/11503
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 4b7c25797..faa12f484 100644
--- a/src/doc/rustc-dev-guide/src/part-5-intro.md
+++ b/src/doc/rustc-dev-guide/src/part-5-intro.md
@@ -1,54 +1,57 @@
# From MIR to Binaries
-All of the preceding chapters of this guide have one thing in common: we never
-generated any executable machine code at all! With this chapter, all of that
-changes.
+All of the preceding chapters of this guide have one thing in common:
+we never generated any executable machine code at all!
+With this chapter, all of that changes.
-So far, we've shown how the compiler can take raw source code in text format
-and transform it into [MIR]. We have also shown how the compiler does various
-analyses on the code to detect things like type or lifetime errors. Now, we
-will finally take the MIR and produce some executable machine code.
+So far,
+we've shown how the compiler can take raw source code in text format
+and transform it into [MIR].
+We have also shown how the compiler does various
+analyses on the code to detect things like type or lifetime errors.
+Now, we will finally take the MIR and produce some executable machine code.
[MIR]: ./mir/index.md
-> NOTE: This part of a compiler is often called the _backend_. The term is a bit
-> overloaded because in the compiler source, it usually refers to the "codegen
-> backend" (i.e. LLVM or Cranelift). Usually, when you see the word "backend"
-> in this part, we are referring to the "codegen backend".
+> NOTE: This part of a compiler is often called the _backend_.
+> The term is a bit overloaded because in the compiler source,
+> it usually refers to the "codegen backend" (i.e. LLVM, Cranelift, or GCC).
+> Usually, when you see the word "backend" in this part,
+> we are referring to the "codegen backend".
So what do we need to do?
-0. 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_.
+0. 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
(usually LLVM IR) for each concrete type we collected.
-2. Finally, we need to invoke LLVM or Cranelift, which runs a bunch of
- optimization passes, generates executable code, and links together an
- executable binary.
+2. Finally, we need to invoke the codegen backend,
+ which runs a bunch of optimization passes,
+ generates executable code,
+ and links together an executable binary.
[codegen1]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/base/fn.codegen_crate.html
The code for codegen is actually a bit complex due to a few factors:
-- Support for multiple codegen backends (LLVM and Cranelift). We try to share as much
- backend code between them as possible, so a lot of it is generic over the
- codegen implementation. This means that there are often a lot of layers of
- abstraction.
+- Support for multiple codegen backends (LLVM, Cranelift, and GCC).
+ We try to share as much backend code between them as possible,
+ so a lot of it is generic over the codegen implementation.
+ This means that there are often a lot of layers of abstraction.
- Codegen happens asynchronously in another thread for performance.
-- The actual codegen is done by a third-party library (either LLVM or Cranelift).
+- The actual codegen is done by a third-party library (either of the 3 backends).
-Generally, the [`rustc_codegen_ssa`][ssa] crate contains backend-agnostic code
-(i.e. independent of LLVM or Cranelift), while the [`rustc_codegen_llvm`][llvm]
-crate contains code specific to LLVM codegen.
+Generally, the [`rustc_codegen_ssa`][ssa] crate contains backend-agnostic code,
+while the [`rustc_codegen_llvm`][llvm] crate contains code specific to LLVM codegen.
[ssa]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/index.html
[llvm]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_llvm/index.html
At a very high level, the entry point is
-[`rustc_codegen_ssa::base::codegen_crate`][codegen1]. This function starts the
-process discussed in the rest of this chapter.
-
+[`rustc_codegen_ssa::base::codegen_crate`][codegen1].
+This function starts the process discussed in the rest of this chapter.
diff --git a/src/doc/rustc-dev-guide/src/profiling.md b/src/doc/rustc-dev-guide/src/profiling.md
index ada497d88..e1666e237 100644
--- a/src/doc/rustc-dev-guide/src/profiling.md
+++ b/src/doc/rustc-dev-guide/src/profiling.md
@@ -108,6 +108,6 @@ The llvm-lines output is affected by several options.
MIR optimizations have little impact. Compared to the default `RUSTFLAGS="-Z
mir-opt-level=1"`, level 0 adds 0.3GB and level 2 removes 0.2GB.
-As of <!-- date: 2022-07 --> July 2022,
+As of <!-- date-check --> July 2022,
inlining happens in LLVM and GCC codegen backends,
missing only in the Cranelift one.
diff --git a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
index b84a5dac4..8a08f1e04 100644
--- a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
+++ b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md
@@ -76,7 +76,7 @@ executed, no results are cached. But the context already provides access to
"input" data, i.e. pieces of immutable data that were computed before the
context was created and that queries can access to do their computations.
-As of <!-- date: 2021-01 --> January 2021, this input data consists mainly of
+As of <!-- date-check --> January 2021, this input data consists mainly of
the HIR map, upstream crate metadata, and the command-line options the compiler
was invoked with; but in the future inputs will just consist of command-line
options and a list of source files -- the HIR map will itself be provided by a
diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md
index 95e570dfc..3d60059bd 100644
--- a/src/doc/rustc-dev-guide/src/query.md
+++ b/src/doc/rustc-dev-guide/src/query.md
@@ -3,7 +3,7 @@
<!-- toc -->
As described in [the high-level overview of the compiler][hl], the Rust compiler
-is still (as of <!-- date: 2021-07 --> July 2021) transitioning from a
+is still (as of <!-- date-check --> July 2021) transitioning from a
traditional "pass-based" setup to a "demand-driven" system. The compiler query
system is the key to rustc's demand-driven organization.
The idea is pretty simple. Instead of entirely independent passes
diff --git a/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md b/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md
index 327415e5a..5ce93c3df 100644
--- a/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md
+++ b/src/doc/rustc-dev-guide/src/rustc-driver-getting-diagnostics.md
@@ -7,7 +7,7 @@
To get diagnostics from the compiler,
configure `rustc_interface::Config` to output diagnostic to a buffer,
and run `TyCtxt.analysis`. The following was tested
-with <!-- date: 2022-06 --> `nightly-2022-06-05` (See [here][example]
+with <!-- date-check: June 2022 --> `nightly-2022-06-05` (See [here][example]
for the complete example):
[example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-driver-getting-diagnostics.rs
diff --git a/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md b/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md
index d70264fe4..ce53f3861 100644
--- a/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md
+++ b/src/doc/rustc-dev-guide/src/rustc-driver-interacting-with-the-ast.md
@@ -5,7 +5,7 @@
## Getting the type of an expression
To get the type of an expression, use the `global_ctxt` to get a `TyCtxt`.
-The following was tested with <!-- date: 2022-06 --> `nightly-2022-06-05`
+The following was tested with <!-- date-check: June 2022 --> `nightly-2022-06-05`
(see [here][example] for the complete example):
[example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-driver-interacting-with-the-ast.rs
diff --git a/src/doc/rustc-dev-guide/src/rustc-driver.md b/src/doc/rustc-dev-guide/src/rustc-driver.md
index 7250c852c..cef50111d 100644
--- a/src/doc/rustc-dev-guide/src/rustc-driver.md
+++ b/src/doc/rustc-dev-guide/src/rustc-driver.md
@@ -7,7 +7,7 @@ using the interface defined in the [`rustc_interface`] crate.
The `rustc_interface` crate provides external users with an (unstable) API
for running code at particular times during the compilation process, allowing
third parties to effectively use `rustc`'s internals as a library for
-analyzing a crate or emulating the compiler in-process (e.g. the RLS or rustdoc).
+analyzing a crate or emulating the compiler in-process (e.g. rustdoc).
For those using `rustc` as a library, the [`rustc_interface::run_compiler()`][i_rc]
function is the main entrypoint to the compiler. It takes a configuration for the compiler
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
index 91bb0c358..f21c8725c 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: 2022-05 --> May 2022:
+Here is the list of passes as of <!-- date-check --> May 2022:
- `calculate-doc-coverage` calculates information used for the `--show-coverage`
flag.
diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md
index 4cdda5a3e..23428efd6 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc.md
@@ -148,7 +148,7 @@ authors can request rebuilds, which will be run with the latest rustdoc.
Docs.rs performs some transformations on rustdoc's output in order to save
storage and display a navigation bar at the top. In particular, certain static
-files (like main.js and rustdoc.css may be shared across multiple invocations
+files, like main.js and rustdoc.css, may be shared across multiple invocations
of the same version of rustdoc. Others, like crates.js and sidebar-items.js, are
different for different invocations. Still others, like fonts, will never
change. These categories are distinguished using the `SharedResource` enum in
diff --git a/src/doc/rustc-dev-guide/src/salsa.md b/src/doc/rustc-dev-guide/src/salsa.md
index afa01eda2..872308e78 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: 2022-04 --> April 2022, although Salsa is inspired by
+> As of <!-- date-check --> April 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 3469ce2ba..b7308ee73 100644
--- a/src/doc/rustc-dev-guide/src/stability.md
+++ b/src/doc/rustc-dev-guide/src/stability.md
@@ -74,13 +74,11 @@ 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
the FCP to complete (with `disposition-merge`).
-1. Change `#[unstable(...)]` to `#[stable(since = "version")]`.
- `version` should be the *current nightly*, i.e. stable+2. You can see which version is
- the current nightly [on Forge](https://forge.rust-lang.org/#current-release-versions).
+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
compiler or tools, remove it from there as well.
3. If applicable, change `#[rustc_const_unstable(...)]` to
- `#[rustc_const_stable(since = "version")]`.
+ `#[rustc_const_stable(since = "CURRENT_RUSTC_VERSION")]`.
4. 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/stabilization_guide.md b/src/doc/rustc-dev-guide/src/stabilization_guide.md
index 454cd0f27..0ac19293b 100644
--- a/src/doc/rustc-dev-guide/src/stabilization_guide.md
+++ b/src/doc/rustc-dev-guide/src/stabilization_guide.md
@@ -99,24 +99,6 @@ require steps beyond what this guide talks about.
Note: Before we stabilize any feature, it's the rule that it
should appear in the documentation.
-### Determining the stabilization version
-
-The version in which the feature will be stabilized *must* match
-the value of [the `src/version` file in `master`][src-version] when the PR is merged.
-
-It's worth checking [the version schedule on the Forge][forge-versions] to see whether
-changes are coming soon. You'll usually use the version labelled "Nightly".
-"Nightly" is two versions higher than the current stable release,
-since what's currently in beta will be the next stable release,
-and any changes you're making now will be in the one after that.
-
-No PR is merged instantly, so you'll want to be careful around release time.
-The version bump happens [the Friday before][forge-release-process] the stable release,
-not the same time as the release. So if you're opening a PR shortly before then,
-be prepared to update the version, or consider just opening it for one version
-higher than the current nightly, with a note saying not to merge until
-after the upcoming version bump.
-
### Updating the feature-gate listing
There is a central listing of feature-gates in
@@ -127,7 +109,7 @@ to stabilize, something like (this example is taken from
```rust,ignore
// pub(restricted) visibilities (RFC 1422)
-(active, pub_restricted, "1.9.0", Some(32409)),
+(active, pub_restricted, "CURRENT_RUSTC_VERSION", Some(32409)),
```
The above line should be moved down to the area for "accepted"
@@ -136,11 +118,13 @@ When it is done, it should look like:
```rust,ignore
// pub(restricted) visibilities (RFC 1422)
-(accepted, pub_restricted, "1.31.0", Some(32409)),
+(accepted, pub_restricted, "CURRENT_RUSTC_VERSION", Some(32409)),
// note that we changed this
```
-(The version here is the one discussed in the previous section.)
+(Even though you will encounter version numbers in the file of past changes,
+you should not put the rustc version you expect your stabilization to happen in,
+but instead `CURRENT_RUSTC_VERSION`)
### Removing existing uses of the feature-gate
diff --git a/src/doc/rustc-dev-guide/src/test-implementation.md b/src/doc/rustc-dev-guide/src/test-implementation.md
index 09a66cdc9..1b8247005 100644
--- a/src/doc/rustc-dev-guide/src/test-implementation.md
+++ b/src/doc/rustc-dev-guide/src/test-implementation.md
@@ -155,5 +155,4 @@ $ rustc my_mod.rs -Z unpretty=hir
[TestDesc]: https://doc.rust-lang.org/test/struct.TestDesc.html
[Symbol]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Symbol.html
[Ident]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Ident.html
-[eRFC]: https://github.com/rust-lang/rfcs/blob/master/text/2318-custom-test-frameworks.md
[rustc_ast]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_ast
diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md
index 21f834130..cca4973cb 100644
--- a/src/doc/rustc-dev-guide/src/tests/ci.md
+++ b/src/doc/rustc-dev-guide/src/tests/ci.md
@@ -2,9 +2,10 @@
## Testing infrastructure
+<!-- date-check: oct 2022 -->
When a Pull Request is opened on GitHub, [GitHub Actions] will automatically
launch a build that will run all tests on some configurations
-(x86_64-gnu-llvm-12 linux. x86_64-gnu-tools linux, mingw-check linux).
+(x86_64-gnu-llvm-13 linux, x86_64-gnu-tools linux, and mingw-check linux).
In essence, each runs `./x.py test` with various different options.
The integration bot [bors] is used for coordinating merges to the master branch.
diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md
index 5c3dcf54b..70cef2ad3 100644
--- a/src/doc/rustc-dev-guide/src/tests/compiletest.md
+++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md
@@ -452,7 +452,7 @@ fn main() {
## Revisions
-Certain classes of tests support "revisions" (as of <!-- date: 2022-07 --> July 2022,
+Certain classes of tests support "revisions" (as of <!-- date-check --> July 2022,
this includes UI, assembly, codegen, debuginfo, incremental, and rustdoc UI tests,
though incremental tests are somewhat different).
Revisions allow a single test file to be used for multiple tests.
diff --git a/src/doc/rustc-dev-guide/src/tests/intro.md b/src/doc/rustc-dev-guide/src/tests/intro.md
index 8b65e4df5..66e0a9eef 100644
--- a/src/doc/rustc-dev-guide/src/tests/intro.md
+++ b/src/doc/rustc-dev-guide/src/tests/intro.md
@@ -115,7 +115,7 @@ will unpack, build, and run all tests.
### Tool tests
Packages that are included with Rust have all of their tests run as well.
-This includes things such as cargo, clippy, rustfmt, rls, miri, bootstrap
+This includes things such as cargo, clippy, rustfmt, miri, bootstrap
(testing the Rust build system itself), etc.
Most of the tools are located in the [`src/tools`] directory.
diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md
index be9d965e4..5d1441936 100644
--- a/src/doc/rustc-dev-guide/src/tests/running.md
+++ b/src/doc/rustc-dev-guide/src/tests/running.md
@@ -245,14 +245,20 @@ The binary will be created at
`./build/$HOST_ARCH/stage2-tools/$TARGET_ARCH/release/remote-test-server`. Copy
this over to the remote machine.
-On the remote machine, run the `remote-test-server` with the `remote` argument
-(and optionally `-v` for verbose output). Output should look like this:
+On the remote machine, run the `remote-test-server` with the `--bind
+0.0.0.0:12345` flag (and optionally `-v` for verbose output). Output should
+look like this:
```sh
-$ ./remote-test-server -v remote
+$ ./remote-test-server -v --bind 0.0.0.0:12345
starting test server
listening on 0.0.0.0:12345!
```
+Note that binding the server to 0.0.0.0 will allow all hosts able to reach your
+machine to execute arbitrary code on your machine. We strongly recommend either
+setting up a firewall to block external access to port 12345, or to use a more
+restrictive IP address when binding.
+
You can test if the `remote-test-server` is working by connecting to it and
sending `ping\n`. It should reply `pong`:
```sh
diff --git a/src/doc/rustc-dev-guide/src/the-parser.md b/src/doc/rustc-dev-guide/src/the-parser.md
index ff43220c1..0d37704e8 100644
--- a/src/doc/rustc-dev-guide/src/the-parser.md
+++ b/src/doc/rustc-dev-guide/src/the-parser.md
@@ -1,6 +1,6 @@
# Lexing and Parsing
-As of <!-- date: 2021-01 --> January 2021, the lexer and parser are undergoing
+As of <!-- date-check --> January 2021, the lexer and parser are undergoing
refactoring to allow extracting them into libraries.
The very first thing the compiler does is take the program (in Unicode
@@ -35,9 +35,10 @@ The main entrypoint to the parser is via the various `parse_*` functions and oth
the token stream, and then execute the parser to get a `Crate` (the root AST
node).
-To minimise the amount of copying that is done, both the `StringReader` and
-`Parser` have lifetimes which bind them to the parent `ParseSess`. This contains
-all the information needed while parsing, as well as the `SourceMap` itself.
+To minimize the amount of copying that is done,
+both [`StringReader`] and [`Parser`] have lifetimes which bind them to the parent `ParseSess`.
+This contains all the information needed while parsing,
+as well as the [`SourceMap`] itself.
Note that while parsing, we may encounter macro definitions or invocations. We
set these aside to be expanded (see [this chapter](./macro-expansion.md)).
@@ -52,9 +53,9 @@ Code for lexical analysis is split between two crates:
constituting tokens. Although it is popular to implement lexers as generated
finite state machines, the lexer in `rustc_lexer` is hand-written.
-- [`StringReader`] from [`rustc_ast`][rustc_ast] integrates `rustc_lexer` with `rustc`
- specific data structures. Specifically, it adds `Span` information to tokens
- returned by `rustc_lexer` and interns identifiers.
+- [`StringReader`] integrates `rustc_lexer` with data structures specific to `rustc`.
+ Specifically,
+ it adds `Span` information to tokens returned by `rustc_lexer` and interns identifiers.
[rustc_ast]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/index.html
[rustc_errors]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html
@@ -64,7 +65,7 @@ Code for lexical analysis is split between two crates:
[rustc_parse]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
[parser_lib]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
[parser]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/index.html
-[`Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/parse/parser/struct.Parser.html
+[`Parser`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html
[`StringReader`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.StringReader.html
[visit module]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/visit/index.html
[sourcefile]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.SourceFile.html
diff --git a/src/doc/rustc-dev-guide/src/thir.md b/src/doc/rustc-dev-guide/src/thir.md
index 4f8e6512c..2a811be3d 100644
--- a/src/doc/rustc-dev-guide/src/thir.md
+++ b/src/doc/rustc-dev-guide/src/thir.md
@@ -4,7 +4,7 @@
The THIR ("Typed High-Level Intermediate Representation"), previously called HAIR for
"High-Level Abstract IR", is another IR used by rustc that is generated after
-[type checking]. It is (as of <!-- date: 2022-04 --> April 2022) only used for
+[type checking]. It is (as of <!-- date-check --> April 2022) only used for
[MIR construction] and [exhaustiveness checking]. There is also
[an experimental unsafety checker][thir-unsafeck] that operates on the THIR as a replacement for
the current MIR unsafety checker, and can be used instead of the MIR unsafety checker by passing
@@ -47,9 +47,19 @@ which is useful to keep peak memory in check. Having a THIR representation of
all bodies of a crate in memory at the same time would be very heavy.
You can get a debug representation of the THIR by passing the `-Zunpretty=thir-tree` flag
-to `rustc`. Here is how a function with just the statement `let x = 1 + 2;` gets represented in
-THIR:
+to `rustc`.
+
+To demonstrate, let's use the following example:
+
```rust
+fn main() {
+ let x = 1 + 2;
+}
+```
+
+Here is how that gets represented in THIR (as of <!-- date-check --> Aug 2022):
+
+```rust,no_run
Thir {
// no match arms
arms: [],
@@ -57,57 +67,73 @@ Thir {
// expression 0, a literal with a value of 1
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:13: 2:14 (#0),
kind: Literal {
- literal: Const {
- ty: i32,
- val: Value(Scalar(0x00000001)),
+ lit: Spanned {
+ node: Int(
+ 1,
+ Unsuffixed,
+ ),
+ span: oneplustwo.rs:2:13: 2:14 (#0),
},
- user_ty: None,
- const_id: None,
+ neg: false,
},
},
// expression 1, scope surronding literal 1
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:13: 2:14 (#0),
kind: Scope {
- region_scope: Node(1),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 1,
- }),
// reference to expression 0 above
+ region_scope: Node(3),
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 3,
+ },
+ ),
value: e0,
},
},
// expression 2, literal 2
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:17: 2:18 (#0),
kind: Literal {
- literal: Const {
- ty: i32,
- val: Value(Scalar(0x00000002)),
+ lit: Spanned {
+ node: Int(
+ 2,
+ Unsuffixed,
+ ),
+ span: oneplustwo.rs:2:17: 2:18 (#0),
},
- user_ty: None,
- const_id: None,
+ neg: false,
},
},
// expression 3, scope surrounding literal 2
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:17: 2:18 (#0),
kind: Scope {
- region_scope: Node(2),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 2,
- }),
+ region_scope: Node(4),
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 4,
+ },
+ ),
// reference to expression 2 above
value: e2,
},
@@ -115,7 +141,9 @@ Thir {
// expression 4, represents 1 + 2
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:13: 2:18 (#0),
kind: Binary {
op: Add,
@@ -127,30 +155,38 @@ Thir {
// expression 5, scope surronding expression 4
Expr {
ty: i32,
- temp_lifetime: Some(Node(6)),
+ temp_lifetime: Some(
+ Node(1),
+ ),
span: oneplustwo.rs:2:13: 2:18 (#0),
kind: Scope {
- region_scope: Node(3),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 3,
- }),
+ region_scope: Node(5),
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 5,
+ },
+ ),
value: e4,
},
},
// expression 6, block around statement
Expr {
ty: (),
- temp_lifetime: Some(Node(8)),
+ temp_lifetime: Some(
+ Node(9),
+ ),
span: oneplustwo.rs:1:11: 3:2 (#0),
kind: Block {
body: Block {
targeted_by_break: false,
- region_scope: Node(7),
+ region_scope: Node(8),
opt_destruction_scope: None,
span: oneplustwo.rs:1:11: 3:2 (#0),
// reference to statement 0 below
- stmts: [ s0 ],
+ stmts: [
+ s0,
+ ],
expr: None,
safety_mode: Safe,
},
@@ -160,25 +196,29 @@ Thir {
Expr {
ty: (),
temp_lifetime: Some(
- Node(8),
+ Node(9),
),
span: oneplustwo.rs:1:11: 3:2 (#0),
kind: Scope {
- region_scope: Node(8),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 8,
- }),
+ region_scope: Node(9),
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 9,
+ },
+ ),
value: e6,
},
},
// destruction scope around expression 7
Expr {
ty: (),
- temp_lifetime: Some(Node(8)),
+ temp_lifetime: Some(
+ Node(9),
+ ),
span: oneplustwo.rs:1:11: 3:2 (#0),
kind: Scope {
- region_scope: Destruction(8),
+ region_scope: Destruction(9),
lint_level: Inherited,
value: e7,
},
@@ -188,8 +228,8 @@ Thir {
// let statement
Stmt {
kind: Let {
- remainder_scope: Remainder { block: 7, first_statement_index: 0},
- init_scope: Node(6),
+ remainder_scope: Remainder { block: 8, first_statement_index: 0},
+ init_scope: Node(1),
pattern: Pat {
ty: i32,
span: oneplustwo.rs:2:9: 2:10 (#0),
@@ -197,22 +237,31 @@ Thir {
mutability: Not,
name: "x",
mode: ByValue,
- var: HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 5,
- },
+ var: LocalVarId(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 7,
+ },
+ ),
ty: i32,
subpattern: None,
is_primary: true,
},
},
- initializer: Some(e5),
- lint_level: Explicit(HirId {
- owner: DefId(0:3 ~ oneplustwo[6ccc]::main),
- local_id: 4,
- }),
+ initializer: Some(
+ e5,
+ ),
+ else_block: None,
+ lint_level: Explicit(
+ HirId {
+ owner: DefId(0:3 ~ oneplustwo[6932]::main),
+ local_id: 6,
+ },
+ ),
},
- opt_destruction_scope: Some(Destruction(6)),
+ opt_destruction_scope: Some(
+ Destruction(1),
+ ),
},
],
}
diff --git a/src/doc/rustc-dev-guide/src/traits/chalk.md b/src/doc/rustc-dev-guide/src/traits/chalk.md
index d4045c460..78deb3675 100644
--- a/src/doc/rustc-dev-guide/src/traits/chalk.md
+++ b/src/doc/rustc-dev-guide/src/traits/chalk.md
@@ -1,7 +1,7 @@
# Chalk-based trait solving
-[Chalk][chalk] is an experimental trait solver for Rust that is (as of <!--
-date: 2022-05 --> May 2022) under development by the [Types team].
+[Chalk][chalk] is an experimental trait solver for Rust that is
+(as of <!-- date-check --> May 2022) under development by the [Types team].
Its goal is to enable a lot of trait system features and bug fixes
that are hard to implement (e.g. GATs or specialization). If you would like to
help in hacking on the new solver, drop by on the rust-lang Zulip in the [`#t-types`]
diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md
index c22ee6de6..88767ad94 100644
--- a/src/doc/rustc-dev-guide/src/traits/resolution.md
+++ b/src/doc/rustc-dev-guide/src/traits/resolution.md
@@ -72,10 +72,10 @@ Trait resolution consists of three major parts:
are completely fulfilled. Basically it is a worklist of obligations
to be selected: once selection is successful, the obligation is
removed from the worklist and any nested obligations are enqueued.
+ Fulfillment constrains inference variables.
-- **Coherence**: The coherence checks are intended to ensure that there
- are never overlapping impls, where two impls could be used with
- equal precedence.
+- **Evaluation**: Checks whether obligations holds without constraining
+ any inference variables. Used by selection.
## Selection
@@ -111,6 +111,8 @@ may lead to other errors downstream).
### Candidate assembly
+**TODO**: Talk about _why_ we have different candidates, and why it needs to happen in a probe.
+
Searches for impls/where-clauses/etc that might
possibly be used to satisfy the obligation. Each of those is called
a candidate. To avoid ambiguity, we want to find exactly one
@@ -120,68 +122,23 @@ the obligation contains unbound inference variables.
The subroutines that decide whether a particular impl/where-clause/etc applies
to a particular obligation are collectively referred to as the process of
-_matching_. As of <!-- date: 2022-05 --> May 2022, this amounts to unifying
-the `Self` types, but in the future we may also recursively consider some of the
-nested obligations, in the case of an impl.
-
-**TODO**: what does "unifying the `Self` types" mean? The `Self` of the
-obligation with that of an impl?
-
-The basic idea for candidate assembly is to do a first pass in which
-we identify all possible candidates. During this pass, all that we do
-is try and unify the type parameters. (In particular, we ignore any
-nested where clauses.) Presuming that this unification succeeds, the
-impl is added as a candidate.
+_matching_. For `impl` candidates <!-- date-check: Oct 2022 -->,
+this amounts to unifying the impl header (the `Self` type and the trait arguments)
+while ignoring nested obligations. If matching succeeds then we add it
+to a set of candidates. There are other rules when assembling candidates for
+built-in traits such as `Copy`, `Sized`, and `CoerceUnsized`.
Once this first pass is done, we can examine the set of candidates. If
it is a singleton set, then we are done: this is the only impl in
-scope that could possibly apply. Otherwise, we can winnow down the set
-of candidates by using where clauses and other conditions. If this
-reduced set yields a single, unambiguous entry, we're good to go,
-otherwise the result is considered ambiguous.
-
-#### The basic process: Inferring based on the impls we see
-
-This process is easier if we work through some examples. Consider
-the following trait:
-
-```rust,ignore
-trait Convert<Target> {
- fn convert(&self) -> Target;
-}
-```
+scope that could possibly apply. Otherwise, we can **winnow** down the set
+of candidates by using where clauses and other conditions. Winnowing uses
+`evaluate_candidate` to check whether the nested obligations may apply.
+If this still leaves more than 1 candidate, we use ` fn candidate_should_be_dropped_in_favor_of`
+to prefer some candidates over others.
-This trait just has one method. It's about as simple as it gets. It
-converts from the (implicit) `Self` type to the `Target` type. If we
-wanted to permit conversion between `isize` and `usize`, we might
-implement `Convert` like so:
-```rust,ignore
-impl Convert<usize> for isize { ... } // isize -> usize
-impl Convert<isize> for usize { ... } // usize -> isize
-```
-
-Now imagine there is some code like the following:
-
-```rust,ignore
-let x: isize = ...;
-let y = x.convert();
-```
-
-The call to convert will generate a trait reference `Convert<$Y> for
-isize`, where `$Y` is the type variable representing the type of
-`y`. Of the two impls we can see, the only one that matches is
-`Convert<usize> for isize`. Therefore, we can
-select this impl, which will cause the type of `$Y` to be unified to
-`usize`. (Note that while assembling candidates, we do the initial
-unifications in a transaction, so that they don't affect one another.)
-
-**TODO**: The example says we can "select" the impl, but this section is
-talking specifically about candidate assembly. Does this mean we can sometimes
-skip confirmation? Or is this poor wording?
-**TODO**: Is the unification of `$Y` part of trait resolution or type
-inference? Or is this not the same type of "inference variable" as in type
-inference?
+If this reduced set yields a single, unambiguous entry, we're good to go,
+otherwise the result is considered ambiguous.
#### Winnowing: Resolving ambiguities
@@ -281,38 +238,18 @@ result of selection would be an error.
Note that the candidate impl is chosen based on the `Self` type, but
confirmation is done based on (in this case) the `Target` type parameter.
-### Selection during translation
+### Selection during codegen
As mentioned above, during type checking, we do not store the results of trait
-selection. At trans time, we repeat the trait selection to choose a particular
-impl for each method call. In this second selection, we do not consider any
-where-clauses to be in scope because we know that each resolution will resolve
-to a particular impl.
-
-One interesting twist has to do with nested obligations. In general, in trans,
-we only need to do a "shallow" selection for an obligation. That is, we wish to
-identify which impl applies, but we do not (yet) need to decide how to select
-any nested obligations. Nonetheless, we *do* currently do a complete resolution,
-and that is because it can sometimes inform the results of type inference.
+selection. At codegen time, we repeat the trait selection to choose a particular
+impl for each method call. This is done using `fn codegen_select_candidate`.
+In this second selection, we do not consider any where-clauses to be in scope
+because we know that each resolution will resolve to a particular impl.
+
+One interesting twist has to do with nested obligations. In general, in codegen,
+we only to figure out which candidate applies, we do not care about nested obligations,
+as these are already assumed to be true. Nonetheless, we *do* currently do fulfill all of them.
+That is because it can sometimes inform the results of type inference.
That is, we do not have the full substitutions in terms of the type variables
of the impl available to us, so we must run trait selection to figure
everything out.
-
-**TODO**: is this still talking about trans?
-
-Here is an example:
-
-```rust,ignore
-trait Foo { ... }
-impl<U, T:Bar<U>> Foo for Vec<T> { ... }
-
-impl Bar<usize> for isize { ... }
-```
-
-After one shallow round of selection for an obligation like `Vec<isize>
-: Foo`, we would know which impl we want, and we would know that
-`T=isize`, but we do not know the type of `U`. We must select the
-nested obligation `isize : Bar<U>` to find out that `U=usize`.
-
-It would be good to only do *just as much* nested resolution as
-necessary. Currently, though, we just do a full resolution.
diff --git a/src/doc/rustc-dev-guide/src/ty.md b/src/doc/rustc-dev-guide/src/ty.md
index 1cc03fce0..9b35f0d4c 100644
--- a/src/doc/rustc-dev-guide/src/ty.md
+++ b/src/doc/rustc-dev-guide/src/ty.md
@@ -78,7 +78,7 @@ expected type. The [`astconv` module][astconv] is where the code responsible for
but also in other parts of the compiler that want to ask questions like "what argument types does
this function expect?"
-[astconv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/astconv/index.html
+[astconv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/astconv/index.html
**How semantics drive the two instances of `Ty`**
diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md
index 4be9211ee..10f1dd5ef 100644
--- a/src/doc/rustc-dev-guide/src/type-inference.md
+++ b/src/doc/rustc-dev-guide/src/type-inference.md
@@ -45,11 +45,9 @@ tcx.infer_ctxt().enter(|infcx| {
})
```
-Within the closure, `infcx` has the type `InferCtxt<'cx, 'tcx>` for some
-fresh `'cx`, while `'tcx` is the same as outside the inference context.
-(Again, see the [`ty` chapter][ty-ch] for more details on this setup.)
-
-[ty-ch]: ty.html
+Within the closure,
+`infcx` has the type `InferCtxt<'a, 'tcx>` for some fresh `'a`,
+while `'tcx` is the same as outside the inference context.
The `tcx.infer_ctxt` method actually returns a builder, which means
there are some kinds of configuration you can do before the `infcx` is
@@ -72,7 +70,7 @@ inference works, or perhaps this blog post on
[Unification in the Chalk project]: http://smallcultfollowing.com/babysteps/blog/2017/03/25/unification-in-chalk-part-1/
All told, the inference context stores five kinds of inference variables
-(as of <!-- date: 2021-06 --> June 2021):
+(as of <!-- date-check --> June 2021):
- Type variables, which come in three varieties:
- General type variables (the most common). These can be unified with any