Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
bf5adeb
Add reference link for HIR ID validator
reddevilmidzy Mar 12, 2026
df4242f
Document AST lowering implementation
reddevilmidzy Mar 19, 2026
126c923
new on_unimplemented match values
malezjaa Mar 21, 2026
2c09d28
start paragraph with upper case
tshepang Mar 23, 2026
8662d07
Merge pull request #2804 from rust-lang/tshepang/fix
tshepang Mar 23, 2026
6a4a3b3
Update information about adding unit tests
Nokel81 Mar 26, 2026
04cec1e
Tweak wording of adding new tests guide
Nokel81 Mar 26, 2026
ea73452
Merge pull request #2806 from Nokel81/patch-1
jyn514 Mar 26, 2026
c9d6463
Mention GPU notification group
apiraino Mar 26, 2026
6eb9ff6
Explain how nested generic args are represented
khyperia Mar 28, 2026
99f0fd9
reflow sentence regarding early bounds
tshepang Mar 28, 2026
66067c6
Merge pull request #2805 from rust-lang/tshepang-patch-1
tshepang Mar 28, 2026
74b3d55
Fix rustc_hir::Crate links
reddevilmidzy Mar 29, 2026
6071f4d
Merge pull request #2810 from reddevilmidzy/hir-crate
reddevilmidzy Mar 29, 2026
bb21934
Add explanation of default flags for UI tests
reddevilmidzy Mar 30, 2026
5cbbc61
Merge pull request #2811 from rust-lang/ui
jyn514 Mar 30, 2026
10d2822
add chapter on projection vs trait split
lcnr Mar 30, 2026
ee44565
Merge pull request #2812 from lcnr/main
lcnr Mar 30, 2026
4ffd0b5
reword `Self` parameter bullet point
BoxyUwU Mar 30, 2026
9b073a0
Merge pull request #2809 from khyperia/fix-2776
BoxyUwU Mar 30, 2026
dab7d0a
cleanup
lcnr Mar 30, 2026
c29def2
Merge pull request #2813 from lcnr/main
lcnr Mar 30, 2026
20ce0f0
Fix rustc-pull CI workflow
Kobzol Apr 1, 2026
c11636c
Merge pull request #2815 from Kobzol/ci-pr-author
Kobzol Apr 1, 2026
9a01adc
Change 'ConstValue::ByRef' to 'ConstValue::Indirect'
gurry Apr 2, 2026
8616930
Merge pull request #2817 from gurry/patch-1
tshepang Apr 2, 2026
972b088
Merge pull request #2807 from apiraino/add-gpu-target
apiraino Apr 2, 2026
938b564
Extend and tweak the glossary
fmease Nov 4, 2024
4b81ebf
Merge pull request #2818 from fmease/extend-glossary
fmease Apr 2, 2026
9e06819
Update hir::Crate link
reddevilmidzy Apr 3, 2026
004a414
Merge pull request #2820 from reddevilmidzy/hir
reddevilmidzy Apr 3, 2026
48db8c7
Update docs to use `TyCtxtEnsureOk::typeck`
reddevilmidzy Apr 3, 2026
20f89a5
Merge pull request #2819 from reddevilmidzy/typeck
reddevilmidzy Apr 4, 2026
28c9494
Prepare for merging from rust-lang/rust
invalid-email-address Apr 6, 2026
1b2376b
Merge ref '9602bda1dd0c' from rust-lang/rust
invalid-email-address Apr 6, 2026
069e5e0
Merge pull request #2823 from rust-lang/rustc-pull
reddevilmidzy Apr 6, 2026
ca69168
missing pause
tshepang Apr 8, 2026
8b7de24
Merge pull request #2801 from malezjaa/new-on-unimplemented-match-values
tshepang Apr 8, 2026
1b09ce5
Prepare for merging from rust-lang/rust
invalid-email-address Apr 8, 2026
444452b
Merge ref '30d0309fa821' from rust-lang/rust
invalid-email-address Apr 8, 2026
fdb83d4
Merge pull request #2824 from rust-lang/rustc-pull
tshepang Apr 8, 2026
f803c18
Merge pull request #2800 from reddevilmidzy/ast-low
tshepang Apr 8, 2026
97eb1be
sembr src/appendix/code-index.md
tshepang Apr 8, 2026
49b1d75
re-wrap
tshepang Apr 8, 2026
91cfd3b
sembr src/const-eval/interpret.md
tshepang Apr 8, 2026
238aabb
whitespace
tshepang Apr 8, 2026
67ce02b
sembr src/traits/separate-projection-bounds.md
tshepang Apr 8, 2026
66bf17e
slight improvements
tshepang Apr 8, 2026
425b2b3
skipped by sembr tool (due to "e.g.")
tshepang Apr 8, 2026
b03b12e
sembr src/ty-module/generic-arguments.md
tshepang Apr 8, 2026
7440567
re-wrap
tshepang Apr 8, 2026
2554c21
sembr src/hir.md
tshepang Apr 8, 2026
9634bb7
re-wrap
tshepang Apr 8, 2026
d82e7c1
sembr src/rustdoc-internals.md
tshepang Apr 8, 2026
9c0a072
re-wrap
tshepang Apr 8, 2026
da97a7f
sembr src/tests/adding.md
tshepang Apr 8, 2026
050110d
re-flow
tshepang Apr 8, 2026
5f86947
Merge pull request #2826 from rust-lang/tshepang/nits
tshepang Apr 8, 2026
ee33056
Merge pull request #2825 from rust-lang/tshepang/sembr
tshepang Apr 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:
uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
with:
github-app-id: ${{ vars.APP_CLIENT_ID }}
pr-author: "workflows-rustc-dev-guide[bot]"
zulip-stream-id: 196385
zulip-bot-email: "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com"
pr-base-branch: main
Expand Down
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
562dee4820c458d823175268e41601d4c060588a
30d0309fa821f7a0984a9629e0d227ca3c0d2eda
8 changes: 5 additions & 3 deletions src/doc/rustc-dev-guide/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
- [WASI](notification-groups/wasi.md)
- [WebAssembly](notification-groups/wasm.md)
- [Windows](notification-groups/windows.md)
- [GPU target](notification-groups/gpu-target.md)
- [Licenses](./licenses.md)
- [Editions](guides/editions.md)

Expand Down Expand Up @@ -100,9 +101,9 @@
- [Parallel compilation](./parallel-rustc.md)
- [Rustdoc internals](./rustdoc-internals.md)
- [Search](./rustdoc-internals/search.md)
- [The `rustdoc-html` test suite](./rustdoc-internals/rustdoc-html-test-suite.md)
- [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md)
- [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md)
- [The `rustdoc-html` test suite](./rustdoc-internals/rustdoc-html-test-suite.md)
- [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md)
- [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md)
- [GPU offload internals](./offload/internals.md)
- [Installation](./offload/installation.md)
- [Usage](./offload/usage.md)
Expand Down Expand Up @@ -189,6 +190,7 @@
- [Significant changes and quirks](./solve/significant-changes.md)
- [Sharing the trait solver with rust-analyzer](./solve/sharing-crates-with-rust-analyzer.md)
- [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md)
- [Having separate `Trait` and `Projection` bounds](./traits/separate-projection-bounds.md)
- [Variance](./variance.md)
- [Coherence checking](./coherence.md)
- [HIR Type checking](./hir-typeck/summary.md)
Expand Down
8 changes: 4 additions & 4 deletions src/doc/rustc-dev-guide/src/appendix/code-index.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Code Index

rustc has a lot of important data structures. This is an attempt to give some
guidance on where to learn more about some of the key data structures of the
compiler.
rustc has a lot of important data structures.
This is an attempt to give some guidance on where to learn more
about some of the key data structures of the compiler.

Item | Kind | Short description | Chapter | Declaration
----------------|----------|-----------------------------|--------------------|-------------------
`BodyId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/hir.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.BodyId.html)
`Compiler` | struct | Represents a compiler session and can be used to drive a compilation. | [The Rustc Driver and Interface] | [compiler/rustc_interface/src/interface.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Compiler.html)
`ast::Crate` | struct | A syntax-level representation of a parsed crate | [The parser] | [compiler/rustc_ast/src/ast.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.Crate.html)
`rustc_hir::Crate` | struct | A more abstract, compiler-friendly form of a crate's AST | [The Hir] | [compiler/rustc_hir/src/hir.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Crate.html)
`hir::Crate` | struct | A more abstract, compiler-friendly form of a crate's AST | [The Hir] | [compiler/rustc_middle/src/hir/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/struct.Crate.html)
`DefId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/def_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html)
`Diag` | struct | A struct for a compiler diagnostic, such as an error or lint | [Emitting Diagnostics] | [compiler/rustc_errors/src/diagnostic.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html)
`DocContext` | struct | A state container used by rustdoc when crawling through a crate to gather its documentation | [Rustdoc] | [src/librustdoc/core.rs](https://github.com/rust-lang/rust/blob/HEAD/src/librustdoc/core.rs)
Expand Down
72 changes: 48 additions & 24 deletions src/doc/rustc-dev-guide/src/appendix/glossary.md

Large diffs are not rendered by default.

138 changes: 84 additions & 54 deletions src/doc/rustc-dev-guide/src/const-eval/interpret.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Interpreter

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
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.
Expand All @@ -26,7 +27,8 @@ 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
`let param_env = tcx.param_env(length_def_id);`.
The `GlobalId` needed is

```rust,ignore
let gid = GlobalId {
Expand All @@ -36,7 +38,8 @@ let gid = GlobalId {
```

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:
the MIR of the array length expression.
The MIR will look something like this:

```mir
Foo::{{constant}}#0: usize = {
Expand All @@ -59,37 +62,45 @@ 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
`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
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.
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
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`
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
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 it was allocated before the
evaluation. `_0` always refers to that location directly.
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
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`).
`ConstValue::Scalar(computed_value)` (instead of the usual `ConstValue::Indirect`).
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`.
Expand All @@ -107,12 +118,13 @@ the interpreter, but just use the cached result.

The interpreter's outside-facing datastructures can be found in
[rustc_middle/src/mir/interpret](https://github.com/rust-lang/rust/blob/HEAD/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
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;
matching) or `Indirect`, 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
Expand All @@ -122,61 +134,74 @@ 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
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.)
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
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
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,
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
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
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
`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.
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
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
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
`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
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.

Expand All @@ -188,17 +213,19 @@ bytes of its value.
### 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
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.
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.
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
(`Scalar::Ptr`) at integer *type* (`usize`).
This is a problem because we
cannot meaningfully perform integer operations such as division on pointer
values.

Expand All @@ -207,30 +234,33 @@ values.
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
that allow accessing the fields of a `ConstValue` (`Indirect` 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
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/HEAD/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
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.
`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/HEAD/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
) 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_*`.
3 changes: 2 additions & 1 deletion src/doc/rustc-dev-guide/src/diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ You can match on the following names and values, using `name = "value"`:
Only `"MainFunctionType"` is supported.
- `from_desugaring`: Match against a particular variant of the `DesugaringKind` enum.
The desugaring is identified by its variant name, for example
`"QuestionMark"` for `?` desugaring or `"TryBlock"` for `try` blocks.
`"QuestionMark"` for `?` desugaring, or `"TryBlock"` for `try` blocks.
- `Self` and any generic arguments of the trait, like `Self = "alloc::string::String"`
or `Rhs="i32"`.

Expand All @@ -964,6 +964,7 @@ The compiler can provide several values to match on, for example:
- references to said slices and arrays.
- `"fn"`, `"unsafe fn"` or `"#[target_feature] fn"` when self is a function.
- `"{integer}"` and `"{float}"` if the type is a number but we haven't inferred it yet.
- `"{struct}"`, `"{enum}"` and `"{union}"` to match self as an ADT
- combinations of the above, like `"[{integral}; _]"`.

For example, the `Iterator` trait can be filtered in the following way:
Expand Down
Loading
Loading