Skip to content

Commit 385db21

Browse files
authored
Rollup merge of #141962 - BoxyUwU:rdg-push, r=jieyouxu
rustc-dev-guide subtree update r? ``@jieyouxu``
2 parents 7852d99 + 033b829 commit 385db21

File tree

9 files changed

+35
-15
lines changed

9 files changed

+35
-15
lines changed

src/doc/rustc-dev-guide/rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
99e7c15e81385b38a8186b51edc4577d5d7b5bdd
1+
c68032fd4c442d275f4daa571ba19c076106b490

src/doc/rustc-dev-guide/src/autodiff/flags.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ LooseTypes // Risk incorrect derivatives instead of aborting when missing Type I
1616
```
1717

1818
<div class="warning">
19+
1920
`LooseTypes` is often helpful to get rid of Enzyme errors stating `Can not deduce type of <X>` and to be able to run some code. But please keep in mind that this flag absolutely has the chance to cause incorrect gradients. Even worse, the gradients might be correct for certain input values, but not for others. So please create issues about such bugs and only use this flag temporarily while you wait for your bug to be fixed.
21+
2022
</div>
2123

2224
### Benchmark flags

src/doc/rustc-dev-guide/src/coroutine-closures.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1+
# Async closures/"coroutine-closures"
2+
3+
<!-- toc -->
4+
15
Please read [RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html) to understand the general motivation of the feature. This is a very technical and somewhat "vertical" chapter; ideally we'd split this and sprinkle it across all the relevant chapters, but for the purposes of understanding async closures *holistically*, I've put this together all here in one chapter.
26

3-
# Coroutine-closures -- a technical deep dive
7+
## Coroutine-closures -- a technical deep dive
48

59
Coroutine-closures are a generalization of async closures, being special syntax for closure expressions which return a coroutine, notably one that is allowed to capture from the closure's upvars.
610

711
For now, the only usable kind of coroutine-closure is the async closure, and supporting async closures is the extent of this PR. We may eventually support `gen || {}`, etc., and most of the problems and curiosities described in this document apply to all coroutine-closures in general.
812

913
As a consequence of the code being somewhat general, this document may flip between calling them "async closures" and "coroutine-closures". The future that is returned by the async closure will generally be called the "coroutine" or the "child coroutine".
1014

11-
## HIR
15+
### HIR
1216

13-
Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure` whose closure-kind is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`) and whose closure-kind is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2].
17+
Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure`.
18+
The closure-kind of the `hir::Closure` is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`.
19+
The closure-kind of the async block is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2].
1420

1521
[^k1]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_ast_lowering/src/expr.rs#L1147>
1622

@@ -24,7 +30,7 @@ Like `async fn`, when lowering an async closure's body, we need to unconditional
2430

2531
[^l3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_hir_typeck/src/upvar.rs#L250-L256>
2632

27-
## `rustc_middle::ty` Representation
33+
### `rustc_middle::ty` Representation
2834

2935
For the purposes of keeping the implementation mostly future-compatible (i.e. with gen `|| {}` and `async gen || {}`), most of this section calls async closures "coroutine-closures".
3036

@@ -72,7 +78,7 @@ To most easily construct the `Coroutine` that a coroutine-closure returns, you c
7278

7379
Most of the args to that function will be components that you can get out of the `CoroutineArgs`, except for the `goal_kind: ClosureKind` which controls which flavor of coroutine to return based off of the `ClosureKind` passed in -- i.e. it will prepare the by-ref coroutine if `ClosureKind::Fn | ClosureKind::FnMut`, and the by-move coroutine if `ClosureKind::FnOnce`.
7480

75-
## Trait Hierarchy
81+
### Trait Hierarchy
7682

7783
We introduce a parallel hierarchy of `Fn*` traits that are implemented for . The motivation for the introduction was covered in a blog post: [Async Closures](https://hackmd.io/@compiler-errors/async-closures).
7884

@@ -98,11 +104,11 @@ We mention above that "regular" callable types can implement `AsyncFn*`, but the
98104

99105
See the "follow-up: when do..." section below for an elaborated answer. The full answer describes a pretty interesting and hopefully thorough heuristic that is used to ensure that most async closures "just work".
100106

101-
## Tale of two bodies...
107+
### Tale of two bodies...
102108

103109
When async closures are called with `AsyncFn`/`AsyncFnMut`, they return a coroutine that borrows from the closure. However, when they are called via `AsyncFnOnce`, we consume that closure, and cannot return a coroutine that borrows from data that is now dropped.
104110

105-
To work around around this limitation, we synthesize a separate by-move MIR body for calling `AsyncFnOnce::call_once` on a coroutine-closure that can be called by-ref.
111+
To work around this limitation, we synthesize a separate by-move MIR body for calling `AsyncFnOnce::call_once` on a coroutine-closure that can be called by-ref.
106112

107113
This body operates identically to the "normal" coroutine returned from calling the coroutine-closure, except for the fact that it has a different set of upvars, since we must *move* the captures from the parent coroutine-closure into the child coroutine.
108114

@@ -120,7 +126,7 @@ Since we've synthesized a new def id, this query is also responsible for feeding
120126

121127
[^b3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_mir_transform/src/lib.rs#L339-L342>
122128

123-
## Closure signature inference
129+
### Closure signature inference
124130

125131
The closure signature inference algorithm for async closures is a bit more complicated than the inference algorithm for "traditional" closures. Like closures, we iterate through all of the clauses that may be relevant (for the expectation type passed in)[^deduce1].
126132

@@ -173,7 +179,7 @@ s.as_bytes();
173179

174180
So *instead*, we use this alias (in this case, a projection: `AsyncFnKindHelper::Upvars<'env, ...>`) to delay the computation of the *tupled upvars* and give us something to put in its place, while still allowing us to return a `TyKind::Coroutine` (which is a rigid type) and we may successfully confirm the built-in traits we need (in our case, `Future`), since the `Future` implementation doesn't depend on the upvars at all.
175181

176-
## Upvar analysis
182+
### Upvar analysis
177183

178184
By and large, the upvar analysis for coroutine-closures and their child coroutines proceeds like normal upvar analysis. However, there are several interesting bits that happen to account for async closures' special natures:
179185

@@ -262,7 +268,7 @@ let c = async || {
262268

263269
If either of these cases apply, then we should capture the borrow with the lifetime of the parent coroutine-closure's env. Luckily, if this function is not correct, then the program is not unsound, since we still borrowck and validate the choices made from this function -- the only side-effect is that the user may receive unnecessary borrowck errors.
264270

265-
## Instance resolution
271+
### Instance resolution
266272

267273
If a coroutine-closure has a closure-kind of `FnOnce`, then its `AsyncFnOnce::call_once` and `FnOnce::call_once` implementations resolve to the coroutine-closure's body[^res1], and the `Future::poll` of the coroutine that gets returned resolves to the body of the child closure.
268274

@@ -282,7 +288,7 @@ This is represented by the `ConstructCoroutineInClosureShim`[^i1]. The `receiver
282288

283289
[^i3]: <https://github.com/rust-lang/rust/blob/07cbbdd69363da97075650e9be24b78af0bcdd23/compiler/rustc_middle/src/ty/instance.rs#L841>
284290

285-
## Borrow-checking
291+
### Borrow-checking
286292

287293
It turns out that borrow-checking async closures is pretty straightforward. After adding a new `DefiningTy::CoroutineClosure`[^bck1] variant, and teaching borrowck how to generate the signature of the coroutine-closure[^bck2], borrowck proceeds totally fine.
288294

src/doc/rustc-dev-guide/src/normalization.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,13 +265,13 @@ Another problem was that it was not possible to normalize `ParamEnv`s correctly
265265

266266
Given a type such as `for<'a> fn(<?x as Trait<'a>::Assoc>)`, it is not possible to correctly handle this with the old solver's approach to normalization.
267267

268-
If we were to normalize it to `for<'a> fn(?y)` and register a goal to normalize `for<'a> <?x as Trait<'a>>::Assoc -> ?y`, this would result in errors in cases where `<?x as Trait<'a>>::Assoc` normalized to `&'a u32`. The inference variable `?y` would be in a lower [universe][universes] than the placeholders made when instantiating the `for<'a>` binder.
268+
If we were to normalize it to `for<'a> fn(?y)` and register a goal to normalize `for<'a> <?x as Trait<'a>>::Assoc -> ?y`, this would result in errors in cases where `<?x as Trait<'a>>::Assoc` normalized to `&'a u32`. The inference variable `?y` would be in a lower [universe] than the placeholders made when instantiating the `for<'a>` binder.
269269

270270
Leaving the alias unnormalized would also be wrong as the old solver expects all aliases to be rigid. This was a soundness bug before the new solver was stabilized in coherence: [relating projection substs is unsound during coherence](https://github.com/rust-lang/rust/issues/102048).
271271

272272
Ultimately this means that it is not always possible to ensure all aliases inside of a value are rigid.
273273

274-
[universes]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/placeholders_and_universes.html#what-is-a-universe
274+
[universe]: borrow_check/region_inference/placeholders_and_universes.md#what-is-a-universe
275275
[deeply_normalize]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/normalize/trait.NormalizeExt.html#tymethod.deeply_normalize
276276

277277
## Handling uses of diverging aliases

src/doc/rustc-dev-guide/src/tests/ci.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,11 @@ Note that if you start the default try job using `@bors try`, it will skip build
186186
Multiple try builds can execute concurrently across different PRs.
187187
188188
<div class="warning">
189-
bors identify try jobs by commit hash. This means that if you have two PRs
189+
190+
Bors identifies try jobs by commit hash. This means that if you have two PRs
190191
containing the same (latest) commits, running `@bors try` will result in the
191192
*same* try job and it really confuses `bors`. Please refrain from doing so.
193+
192194
</div>
193195
194196
[rustc-perf]: https://github.com/rust-lang/rustc-perf

src/doc/rustc-dev-guide/src/tests/compiletest.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,9 @@ To work around this when working on a particular test, temporarily create a
438438
with these contents:
439439

440440
<div class="warning">
441+
441442
Be careful not to add this `Cargo.toml` or its `Cargo.lock` to your actual PR!
443+
442444
</div>
443445

444446
```toml

src/doc/rustc-dev-guide/src/tests/directives.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,13 @@ ignoring debuggers.
248248
| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
249249

250250
<div class="warning">
251+
251252
Tests (outside of `run-make`) that want to use incremental tests not in the
252253
incremental test-suite must not pass `-C incremental` via `compile-flags`, and
253254
must instead use the `//@ incremental` directive.
254255

255256
Consider writing the test as a proper incremental test instead.
257+
256258
</div>
257259

258260
### Rustdoc

src/doc/rustc-dev-guide/src/tests/minicore.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ ui/codegen/assembly test suites. It provides `core` stubs for tests that need to
77
build for cross-compiled targets but do not need/want to run.
88

99
<div class="warning">
10+
1011
Please note that [`minicore`] is only intended for `core` items, and explicitly
1112
**not** `std` or `alloc` items because `core` items are applicable to a wider
1213
range of tests.
14+
1315
</div>
1416

1517
A test can use [`minicore`] by specifying the `//@ add-core-stubs` directive.

src/doc/rustc-dev-guide/src/tests/running.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ development because it takes a really long time. For local development, see the
88
subsection after on how to run a subset of tests.
99

1010
<div class="warning">
11+
1112
Running plain `./x test` will build the stage 1 compiler and then run the whole
1213
test suite. This not only include `tests/`, but also `library/`, `compiler/`,
1314
`src/tools/` package tests and more.
@@ -16,6 +17,7 @@ You usually only want to run a subset of the test suites (or even a smaller set
1617
of tests than that) which you expect will exercise your changes. PR CI exercises
1718
a subset of test collections, and merge queue CI will exercise all of the test
1819
collection.
20+
1921
</div>
2022

2123
```text
@@ -116,8 +118,10 @@ By listing which test suites you want to run,
116118
you avoid having to run tests for components you did not change at all.
117119

118120
<div class="warning">
121+
119122
Note that bors only runs the tests with the full stage 2 build; therefore, while
120123
the tests **usually** work fine with stage 1, there are some limitations.
124+
121125
</div>
122126

123127
### Run all tests using a stage 2 compiler

0 commit comments

Comments
 (0)