Skip to content

Commit 5d0ff30

Browse files
Rollup merge of #154980 - tshepang:rdg-sync, r=tshepang
rustc-dev-guide subtree update Subtree update of `rustc-dev-guide` to 912f6c6. Created using https://github.com/rust-lang/josh-sync. r? @ghost
2 parents 339fdd0 + 912f6c6 commit 5d0ff30

19 files changed

Lines changed: 417 additions & 186 deletions

File tree

.github/workflows/rustc-pull.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ jobs:
1212
uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
1313
with:
1414
github-app-id: ${{ vars.APP_CLIENT_ID }}
15+
pr-author: "workflows-rustc-dev-guide[bot]"
1516
zulip-stream-id: 196385
1617
zulip-bot-email: "rustc-dev-guide-gha-notif-bot@rust-lang.zulipchat.com"
1718
pr-base-branch: main

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
562dee4820c458d823175268e41601d4c060588a
1+
30d0309fa821f7a0984a9629e0d227ca3c0d2eda

src/SUMMARY.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
- [WASI](notification-groups/wasi.md)
7373
- [WebAssembly](notification-groups/wasm.md)
7474
- [Windows](notification-groups/windows.md)
75+
- [GPU target](notification-groups/gpu-target.md)
7576
- [Licenses](./licenses.md)
7677
- [Editions](guides/editions.md)
7778

@@ -100,9 +101,9 @@
100101
- [Parallel compilation](./parallel-rustc.md)
101102
- [Rustdoc internals](./rustdoc-internals.md)
102103
- [Search](./rustdoc-internals/search.md)
103-
- [The `rustdoc-html` test suite](./rustdoc-internals/rustdoc-html-test-suite.md)
104-
- [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md)
105-
- [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md)
104+
- [The `rustdoc-html` test suite](./rustdoc-internals/rustdoc-html-test-suite.md)
105+
- [The `rustdoc-gui` test suite](./rustdoc-internals/rustdoc-gui-test-suite.md)
106+
- [The `rustdoc-json` test suite](./rustdoc-internals/rustdoc-json-test-suite.md)
106107
- [GPU offload internals](./offload/internals.md)
107108
- [Installation](./offload/installation.md)
108109
- [Usage](./offload/usage.md)
@@ -189,6 +190,7 @@
189190
- [Significant changes and quirks](./solve/significant-changes.md)
190191
- [Sharing the trait solver with rust-analyzer](./solve/sharing-crates-with-rust-analyzer.md)
191192
- [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md)
193+
- [Having separate `Trait` and `Projection` bounds](./traits/separate-projection-bounds.md)
192194
- [Variance](./variance.md)
193195
- [Coherence checking](./coherence.md)
194196
- [HIR Type checking](./hir-typeck/summary.md)

src/appendix/code-index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# Code Index
22

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

77
Item | Kind | Short description | Chapter | Declaration
88
----------------|----------|-----------------------------|--------------------|-------------------
99
`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)
1010
`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)
1111
`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)
12-
`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)
12+
`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)
1313
`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)
1414
`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)
1515
`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)

src/appendix/glossary.md

Lines changed: 48 additions & 24 deletions
Large diffs are not rendered by default.

src/const-eval/interpret.md

Lines changed: 84 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Interpreter
22

33
The interpreter is a virtual machine for executing MIR without compiling to
4-
machine code. It is usually invoked via `tcx.const_eval_*` functions. The
5-
interpreter is shared between the compiler (for compile-time function
4+
machine code.
5+
It is usually invoked via `tcx.const_eval_*` functions.
6+
The interpreter is shared between the compiler (for compile-time function
67
evaluation, CTFE) and the tool [Miri](https://github.com/rust-lang/miri/), which
78
uses the same virtual machine to detect Undefined Behavior in (unsafe) Rust
89
code.
@@ -26,7 +27,8 @@ The compiler needs to figure out the length of the array before being able to
2627
create items that use the type (locals, constants, function arguments, ...).
2728

2829
To obtain the (in this case empty) parameter environment, one can call
29-
`let param_env = tcx.param_env(length_def_id);`. The `GlobalId` needed is
30+
`let param_env = tcx.param_env(length_def_id);`.
31+
The `GlobalId` needed is
3032

3133
```rust,ignore
3234
let gid = GlobalId {
@@ -36,7 +38,8 @@ let gid = GlobalId {
3638
```
3739

3840
Invoking `tcx.const_eval(param_env.and(gid))` will now trigger the creation of
39-
the MIR of the array length expression. The MIR will look something like this:
41+
the MIR of the array length expression.
42+
The MIR will look something like this:
4043

4144
```mir
4245
Foo::{{constant}}#0: usize = {
@@ -59,37 +62,45 @@ Before the evaluation, a virtual memory location (in this case essentially a
5962
`vec![u8; 4]` or `vec![u8; 8]`) is created for storing the evaluation result.
6063

6164
At the start of the evaluation, `_0` and `_1` are
62-
`Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef))`. This is quite
65+
`Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef))`.
66+
This is quite
6367
a mouthful: [`Operand`] can represent either data stored somewhere in the
6468
[interpreter memory](#memory) (`Operand::Indirect`), or (as an optimization)
65-
immediate data stored in-line. And [`Immediate`] can either be a single
69+
immediate data stored in-line.
70+
And [`Immediate`] can either be a single
6671
(potentially uninitialized) [scalar value][`Scalar`] (integer or thin pointer),
67-
or a pair of two of them. In our case, the single scalar value is *not* (yet)
68-
initialized.
72+
or a pair of two of them.
73+
In our case, the single scalar value is *not* (yet) initialized.
6974

7075
When the initialization of `_1` is invoked, the value of the `FOO` constant is
7176
required, and triggers another call to `tcx.const_eval_*`, which will not be shown
72-
here. If the evaluation of FOO is successful, `42` will be subtracted from its
77+
here.
78+
If the evaluation of FOO is successful, `42` will be subtracted from its
7379
value `4096` and the result stored in `_1` as
7480
`Operand::Immediate(Immediate::ScalarPair(Scalar::Raw { data: 4054, .. },
75-
Scalar::Raw { data: 0, .. })`. The first part of the pair is the computed value,
76-
the second part is a bool that's true if an overflow happened. A `Scalar::Raw`
81+
Scalar::Raw { data: 0, .. })`.
82+
The first part of the pair is the computed value,
83+
the second part is a bool that's true if an overflow happened.
84+
A `Scalar::Raw`
7785
also stores the size (in bytes) of this scalar value; we are eliding that here.
7886

79-
The next statement asserts that said boolean is `0`. In case the assertion
87+
The next statement asserts that said boolean is `0`.
88+
In case the assertion
8089
fails, its error message is used for reporting a compile-time error.
8190

8291
Since it does not fail, `Operand::Immediate(Immediate::Scalar(Scalar::Raw {
8392
data: 4054, .. }))` is stored in the virtual memory it was allocated before the
84-
evaluation. `_0` always refers to that location directly.
93+
evaluation.
94+
`_0` always refers to that location directly.
8595

8696
After the evaluation is done, the return value is converted from [`Operand`] to
8797
[`ConstValue`] by [`op_to_const`]: the former representation is geared towards
8898
what is needed *during* const evaluation, while [`ConstValue`] is shaped by the
8999
needs of the remaining parts of the compiler that consume the results of const
90-
evaluation. As part of this conversion, for types with scalar values, even if
100+
evaluation.
101+
As part of this conversion, for types with scalar values, even if
91102
the resulting [`Operand`] is `Indirect`, it will return an immediate
92-
`ConstValue::Scalar(computed_value)` (instead of the usual `ConstValue::ByRef`).
103+
`ConstValue::Scalar(computed_value)` (instead of the usual `ConstValue::Indirect`).
93104
This makes using the result much more efficient and also more convenient, as no
94105
further queries need to be executed in order to get at something as simple as a
95106
`usize`.
@@ -107,12 +118,13 @@ the interpreter, but just use the cached result.
107118

108119
The interpreter's outside-facing datastructures can be found in
109120
[rustc_middle/src/mir/interpret](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_middle/src/mir/interpret).
110-
This is mainly the error enum and the [`ConstValue`] and [`Scalar`] types. A
111-
`ConstValue` can be either `Scalar` (a single `Scalar`, i.e., integer or thin
121+
This is mainly the error enum and the [`ConstValue`] and [`Scalar`] types.
122+
A `ConstValue` can be either `Scalar` (a single `Scalar`, i.e., integer or thin
112123
pointer), `Slice` (to represent byte slices and strings, as needed for pattern
113-
matching) or `ByRef`, which is used for anything else and refers to a virtual
114-
allocation. These allocations can be accessed via the methods on
115-
`tcx.interpret_interner`. A `Scalar` is either some `Raw` integer or a pointer;
124+
matching) or `Indirect`, which is used for anything else and refers to a virtual
125+
allocation.
126+
These allocations can be accessed via the methods on `tcx.interpret_interner`.
127+
A `Scalar` is either some `Raw` integer or a pointer;
116128
see [the next section](#memory) for more on that.
117129

118130
If you are expecting a numeric result, you can use `eval_usize` (panics on
@@ -122,61 +134,74 @@ in an `Option<u64>` yielding the `Scalar` if possible.
122134
## Memory
123135

124136
To support any kind of pointers, the interpreter needs to have a "virtual memory" that the
125-
pointers can point to. This is implemented in the [`Memory`] type. In the
126-
simplest model, every global variable, stack variable and every dynamic
127-
allocation corresponds to an [`Allocation`] in that memory. (Actually using an
137+
pointers can point to.
138+
This is implemented in the [`Memory`] type.
139+
In the simplest model, every global variable, stack variable and every dynamic
140+
allocation corresponds to an [`Allocation`] in that memory.
141+
(Actually using an
128142
allocation for every MIR stack variable would be very inefficient; that's why we
129143
have `Operand::Immediate` for stack variables that are both small and never have
130-
their address taken. But that is purely an optimization.)
144+
their address taken.
145+
But that is purely an optimization.)
131146

132147
Such an `Allocation` is basically just a sequence of `u8` storing the value of
133-
each byte in this allocation. (Plus some extra data, see below.) Every
134-
`Allocation` has a globally unique `AllocId` assigned in `Memory`. With that, a
148+
each byte in this allocation.
149+
(Plus some extra data, see below.) Every
150+
`Allocation` has a globally unique `AllocId` assigned in `Memory`.
151+
With that, a
135152
[`Pointer`] consists of a pair of an `AllocId` (indicating the allocation) and
136153
an offset into the allocation (indicating which byte of the allocation the
137-
pointer points to). It may seem odd that a `Pointer` is not just an integer
154+
pointer points to).
155+
It may seem odd that a `Pointer` is not just an integer
138156
address, but remember that during const evaluation, we cannot know at which
139157
actual integer address the allocation will end up -- so we use `AllocId` as
140-
symbolic base addresses, which means we need a separate offset. (As an aside,
158+
symbolic base addresses, which means we need a separate offset.
159+
(As an aside,
141160
it turns out that pointers at run-time are
142161
[more than just integers, too](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#pointer-provenance).)
143162

144163
These allocations exist so that references and raw pointers have something to
145-
point to. There is no global linear heap in which things are allocated, but each
164+
point to.
165+
There is no global linear heap in which things are allocated, but each
146166
allocation (be it for a local variable, a static or a (future) heap allocation)
147-
gets its own little memory with exactly the required size. So if you have a
167+
gets its own little memory with exactly the required size.
168+
So if you have a
148169
pointer to an allocation for a local variable `a`, there is no possible (no
149170
matter how unsafe) operation that you can do that would ever change said pointer
150171
to a pointer to a different local variable `b`.
151172
Pointer arithmetic on `a` will only ever change its offset; the `AllocId` stays the same.
152173

153174
This, however, causes a problem when we want to store a `Pointer` into an
154175
`Allocation`: we cannot turn it into a sequence of `u8` of the right length!
155-
`AllocId` and offset together are twice as big as a pointer "seems" to be. This
156-
is what the `relocation` field of `Allocation` is for: the byte offset of the
176+
`AllocId` and offset together are twice as big as a pointer "seems" to be.
177+
This is what the `relocation` field of `Allocation` is for: the byte offset of the
157178
`Pointer` gets stored as a bunch of `u8`, while its `AllocId` gets stored
158-
out-of-band. The two are reassembled when the `Pointer` is read from memory.
179+
out-of-band.
180+
The two are reassembled when the `Pointer` is read from memory.
159181
The other bit of extra data an `Allocation` needs is `undef_mask` for keeping
160182
track of which of its bytes are initialized.
161183

162184
### Global memory and exotic allocations
163185

164186
`Memory` exists only during evaluation; it gets destroyed when the
165-
final value of the constant is computed. In case that constant contains any
187+
final value of the constant is computed.
188+
In case that constant contains any
166189
pointers, those get "interned" and moved to a global "const eval memory" that is
167-
part of `TyCtxt`. These allocations stay around for the remaining computation
190+
part of `TyCtxt`.
191+
These allocations stay around for the remaining computation
168192
and get serialized into the final output (so that dependent crates can use
169193
them).
170194

171195
Moreover, to also support function pointers, the global memory in `TyCtxt` can
172196
also contain "virtual allocations": instead of an `Allocation`, these contain an
173-
`Instance`. That allows a `Pointer` to point to either normal data or a
197+
`Instance`.
198+
That allows a `Pointer` to point to either normal data or a
174199
function, which is needed to be able to evaluate casts from function pointers to
175200
raw pointers.
176201

177202
Finally, the [`GlobalAlloc`] type used in the global memory also contains a
178-
variant `Static` that points to a particular `const` or `static` item. This is
179-
needed to support circular statics, where we need to have a `Pointer` to a
203+
variant `Static` that points to a particular `const` or `static` item.
204+
This is needed to support circular statics, where we need to have a `Pointer` to a
180205
`static` for which we cannot yet have an `Allocation` as we do not know the
181206
bytes of its value.
182207

@@ -188,17 +213,19 @@ bytes of its value.
188213
### Pointer values vs Pointer types
189214

190215
One common cause of confusion in the interpreter is that being a pointer *value* and having
191-
a pointer *type* are entirely independent properties. By "pointer value", we
216+
a pointer *type* are entirely independent properties.
217+
By "pointer value", we
192218
refer to a `Scalar::Ptr` containing a `Pointer` and thus pointing somewhere into
193-
the interpreter's virtual memory. This is in contrast to `Scalar::Raw`, which is just some
194-
concrete integer.
219+
the interpreter's virtual memory.
220+
This is in contrast to `Scalar::Raw`, which is just some concrete integer.
195221

196222
However, a variable of pointer or reference *type*, such as `*const T` or `&T`,
197223
does not have to have a pointer *value*: it could be obtained by casting or
198-
transmuting an integer to a pointer.
224+
transmuting an integer to a pointer.
199225
And similarly, when casting or transmuting a reference to some
200226
actual allocation to an integer, we end up with a pointer *value*
201-
(`Scalar::Ptr`) at integer *type* (`usize`). This is a problem because we
227+
(`Scalar::Ptr`) at integer *type* (`usize`).
228+
This is a problem because we
202229
cannot meaningfully perform integer operations such as division on pointer
203230
values.
204231

@@ -207,30 +234,33 @@ values.
207234
Although the main entry point to constant evaluation is the `tcx.const_eval_*`
208235
functions, there are additional functions in
209236
[rustc_const_eval/src/const_eval](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/index.html)
210-
that allow accessing the fields of a `ConstValue` (`ByRef` or otherwise). You should
237+
that allow accessing the fields of a `ConstValue` (`Indirect` or otherwise).
238+
You should
211239
never have to access an `Allocation` directly except for translating it to the
212240
compilation target (at the moment just LLVM).
213241

214242
The interpreter starts by creating a virtual stack frame for the current constant that is
215-
being evaluated. There's essentially no difference between a constant and a
243+
being evaluated.
244+
There's essentially no difference between a constant and a
216245
function with no arguments, except that constants do not allow local (named)
217246
variables at the time of writing this guide.
218247

219248
A stack frame is defined by the `Frame` type in
220249
[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)
221-
and contains all the local
222-
variables memory (`None` at the start of evaluation). Each frame refers to the
223-
evaluation of either the root constant or subsequent calls to `const fn`. The
224-
evaluation of another constant simply calls `tcx.const_eval_*`, which produce an
250+
and contains all the local variables memory (`None` at the start of evaluation).
251+
Each frame refers to the
252+
evaluation of either the root constant or subsequent calls to `const fn`.
253+
The evaluation of another constant simply calls `tcx.const_eval_*`, which produce an
225254
entirely new and independent stack frame.
226255

227256
The frames are just a `Vec<Frame>`, there's no way to actually refer to a
228-
`Frame`'s memory even if horrible shenanigans are done via unsafe code. The only
229-
memory that can be referred to are `Allocation`s.
257+
`Frame`'s memory even if horrible shenanigans are done via unsafe code.
258+
The only memory that can be referred to are `Allocation`s.
230259

231260
The interpreter now calls the `step` method (in
232261
[rustc_const_eval/src/interpret/step.rs](https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_const_eval/src/interpret/step.rs)
233-
) until it either returns an error or has no further statements to execute. Each
234-
statement will now initialize or modify the locals or the virtual memory
235-
referred to by a local. This might require evaluating other constants or
262+
) until it either returns an error or has no further statements to execute.
263+
Each statement will now initialize or modify the locals or the virtual memory
264+
referred to by a local.
265+
This might require evaluating other constants or
236266
statics, which just recursively invokes `tcx.const_eval_*`.

src/diagnostics.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ You can match on the following names and values, using `name = "value"`:
953953
Only `"MainFunctionType"` is supported.
954954
- `from_desugaring`: Match against a particular variant of the `DesugaringKind` enum.
955955
The desugaring is identified by its variant name, for example
956-
`"QuestionMark"` for `?` desugaring or `"TryBlock"` for `try` blocks.
956+
`"QuestionMark"` for `?` desugaring, or `"TryBlock"` for `try` blocks.
957957
- `Self` and any generic arguments of the trait, like `Self = "alloc::string::String"`
958958
or `Rhs="i32"`.
959959

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

969970
For example, the `Iterator` trait can be filtered in the following way:

0 commit comments

Comments
 (0)