Skip to content

Change type of async context parameter after state transform.#157166

Merged
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
cjgillot:retype-context-after
Jun 10, 2026
Merged

Change type of async context parameter after state transform.#157166
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
cjgillot:retype-context-after

Conversation

@cjgillot

@cjgillot cjgillot commented May 30, 2026

Copy link
Copy Markdown
Contributor

View all comments

Future::poll expects a &mut std::task::Context<'_>. Meanwhile, async coroutines use std::future::ResumeTy as resume parameter. This is meant to workaround the limitations of borrowck, which cannot prove that coroutines implement for<'a, 'b> CoroutineTrait<&'a mut Context<'b>>.

In the coroutine state transform, we need to change the signature from ResumeTy to the proper &mut Context<'_>. The current code attempts to find locals that have type ResumeTy to change their type. This is needlessly complex and relies on undocumented behaviour of the MIR builder.

Instead, this PR proposes to replace the ResumeTy argument with a new local, with value ResumeTy(transmute(context)).

Based on #156875.

@rustbot

rustbot commented May 30, 2026

Copy link
Copy Markdown
Collaborator

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 30, 2026
@rustbot

rustbot commented May 30, 2026

Copy link
Copy Markdown
Collaborator

r? @tiif

rustbot has assigned @tiif.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 17 candidates

@rust-log-analyzer

This comment has been minimized.

@cjgillot cjgillot force-pushed the retype-context-after branch from 8447533 to 8c16d8a Compare May 30, 2026 17:54
@rust-log-analyzer

This comment has been minimized.

@cjgillot cjgillot force-pushed the retype-context-after branch from 8c16d8a to ab5076b Compare May 30, 2026 21:12
@rust-log-analyzer

This comment has been minimized.

@cjgillot cjgillot force-pushed the retype-context-after branch from ab5076b to 769048f Compare May 31, 2026 08:02
@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@cjgillot cjgillot force-pushed the retype-context-after branch from 769048f to 89aaf42 Compare May 31, 2026 09:46
@rust-bors

This comment has been minimized.

@cjgillot cjgillot force-pushed the retype-context-after branch from 89aaf42 to 93879f5 Compare June 1, 2026 21:36
@rustbot

This comment has been minimized.

@rust-bors

This comment has been minimized.

@cjgillot cjgillot force-pushed the retype-context-after branch from 93879f5 to 323effe Compare June 3, 2026 21:40
@rustbot

This comment has been minimized.

@cjgillot cjgillot force-pushed the retype-context-after branch from 323effe to b7e26ac Compare June 4, 2026 12:12
@rustbot

rustbot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Comment on lines +612 to +615
/// HIR uses `get_context` to unwrap a `&mut Context<'_>` from a `ResumeTy`.
/// Both types are just a single pointer, but liveness analysis does not know that and
/// supposes that the operand and the destination are live at the same time.
/// Forcibly inline those calls to avoid this.

@oli-obk oli-obk Jun 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preexisting, but: it feels a bit funny to generate a function call in ast lowering only to desugar it here manually. The function body is effectively dead code.

View changes since the review

@oli-obk oli-obk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rust-bors

rust-bors Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

📌 Commit b7e26ac has been approved by oli-obk

It is now in the queue for this repository.

rust-bors Bot pushed a commit that referenced this pull request Jun 9, 2026
Change type of async context parameter after state transform.

`Future::poll` expects a `&mut std::task::Context<'_>`. Meanwhile, async coroutines use `std::future::ResumeTy` as resume parameter. This is meant to workaround the limitations of borrowck, which cannot prove that coroutines implement `for<'a, 'b> CoroutineTrait<&'a mut Context<'b>>`.

In the coroutine state transform, we need to change the signature from `ResumeTy` to the proper `&mut Context<'_>`. The current code attempts to find locals that have type `ResumeTy` to change their type. This is needlessly complex and relies on undocumented behaviour of the MIR builder.

Instead, this PR proposes to replace the `ResumeTy` argument with a new local, with value `ResumeTy(transmute(context))`.

Based on #156875.
@jhpratt

jhpratt commented Jun 9, 2026

Copy link
Copy Markdown
Member

yielding to a rollup=never PR

@bors yield

@rust-bors

rust-bors Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Auto build was cancelled. Cancelled workflows:

The next pull request likely to be tested is #129543.

rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Rollup of 17 pull requests

Successful merges:

 - #157166 (Change type of async context parameter after state transform.)
 - #157335 (bootstrap: Handle dotted table keys when parsing bootstrap.toml)
 - #157503 (Disable `tests/debuginfo/pretty-std.rs` `OsString` cdb check)
 - #157571 (Remove ProcMacro enum from proc macro ABI)
 - #148183 (rustdoc: Test & document `test_harness` code block attribute)
 - #153847 (Fix marker trait winnowing depending on impl order)
 - #156067 (Fix async drop glue for Box<T>)
 - #156399 (fix improper ctypes in Znext solver)
 - #157338 (Make `Literal::byte_character_value` work with bytes as well)
 - #157410 (Implement rustc_public::CrateDef{,Type} for FieldDef)
 - #157605 (Arg splat experiment - syntax impl)
 - #157630 (Add multibyte JSON diagnostic regression test)
 - #157633 (Reorder `impl` restriction rendering and add bottom margin)
 - #157642 (Report duplicate relaxed bounds during ast lowering)
 - #157652 (fix doc for unicode normalization faq on `casefold` APIs)
 - #157661 (Update to ar_archive_writer v0.5.2)
 - #157668 (Add test for matches in `rustc_must_match_exhaustively`)

Failed merges:

 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
@rust-bors

rust-bors Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

⌛ Testing commit b7e26ac with merge 39465ed...

Workflow: https://github.com/rust-lang/rust/actions/runs/27248950736

rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Change type of async context parameter after state transform.

`Future::poll` expects a `&mut std::task::Context<'_>`. Meanwhile, async coroutines use `std::future::ResumeTy` as resume parameter. This is meant to workaround the limitations of borrowck, which cannot prove that coroutines implement `for<'a, 'b> CoroutineTrait<&'a mut Context<'b>>`.

In the coroutine state transform, we need to change the signature from `ResumeTy` to the proper `&mut Context<'_>`. The current code attempts to find locals that have type `ResumeTy` to change their type. This is needlessly complex and relies on undocumented behaviour of the MIR builder.

Instead, this PR proposes to replace the `ResumeTy` argument with a new local, with value `ResumeTy(transmute(context))`.

Based on #156875.
@jhpratt

jhpratt commented Jun 10, 2026

Copy link
Copy Markdown
Member

same thing

@bors yield

@rust-bors

rust-bors Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Auto build was cancelled. Cancelled workflows:

The next pull request likely to be tested is #157683.

rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Rollup of 17 pull requests

Successful merges:

 - #157166 (Change type of async context parameter after state transform.)
 - #157335 (bootstrap: Handle dotted table keys when parsing bootstrap.toml)
 - #157503 (Disable `tests/debuginfo/pretty-std.rs` `OsString` cdb check)
 - #157571 (Remove ProcMacro enum from proc macro ABI)
 - #148183 (rustdoc: Test & document `test_harness` code block attribute)
 - #153847 (Fix marker trait winnowing depending on impl order)
 - #156067 (Fix async drop glue for Box<T>)
 - #156399 (fix improper ctypes in Znext solver)
 - #157338 (Make `Literal::byte_character_value` work with bytes as well)
 - #157410 (Implement rustc_public::CrateDef{,Type} for FieldDef)
 - #157605 (Arg splat experiment - syntax impl)
 - #157630 (Add multibyte JSON diagnostic regression test)
 - #157633 (Reorder `impl` restriction rendering and add bottom margin)
 - #157642 (Report duplicate relaxed bounds during ast lowering)
 - #157652 (fix doc for unicode normalization faq on `casefold` APIs)
 - #157661 (Update to ar_archive_writer v0.5.2)
 - #157668 (Add test for matches in `rustc_must_match_exhaustively`)

Failed merges:

 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
@rust-bors

rust-bors Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

⌛ Testing commit b7e26ac with merge e1e4985...

Workflow: https://github.com/rust-lang/rust/actions/runs/27249369474

rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Change type of async context parameter after state transform.

`Future::poll` expects a `&mut std::task::Context<'_>`. Meanwhile, async coroutines use `std::future::ResumeTy` as resume parameter. This is meant to workaround the limitations of borrowck, which cannot prove that coroutines implement `for<'a, 'b> CoroutineTrait<&'a mut Context<'b>>`.

In the coroutine state transform, we need to change the signature from `ResumeTy` to the proper `&mut Context<'_>`. The current code attempts to find locals that have type `ResumeTy` to change their type. This is needlessly complex and relies on undocumented behaviour of the MIR builder.

Instead, this PR proposes to replace the `ResumeTy` argument with a new local, with value `ResumeTy(transmute(context))`.

Based on #156875.
@jhpratt

jhpratt commented Jun 10, 2026

Copy link
Copy Markdown
Member

repeated network failures; I've closed the tree elsewhere

@bors yield

@rust-bors

rust-bors Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Auto build was cancelled. Cancelled workflows:

The next pull request likely to be tested is #157683.

rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Rollup of 17 pull requests

Successful merges:

 - #157166 (Change type of async context parameter after state transform.)
 - #157335 (bootstrap: Handle dotted table keys when parsing bootstrap.toml)
 - #157503 (Disable `tests/debuginfo/pretty-std.rs` `OsString` cdb check)
 - #157571 (Remove ProcMacro enum from proc macro ABI)
 - #148183 (rustdoc: Test & document `test_harness` code block attribute)
 - #153847 (Fix marker trait winnowing depending on impl order)
 - #156067 (Fix async drop glue for Box<T>)
 - #156399 (fix improper ctypes in Znext solver)
 - #157338 (Make `Literal::byte_character_value` work with bytes as well)
 - #157410 (Implement rustc_public::CrateDef{,Type} for FieldDef)
 - #157605 (Arg splat experiment - syntax impl)
 - #157630 (Add multibyte JSON diagnostic regression test)
 - #157633 (Reorder `impl` restriction rendering and add bottom margin)
 - #157642 (Report duplicate relaxed bounds during ast lowering)
 - #157652 (fix doc for unicode normalization faq on `casefold` APIs)
 - #157661 (Update to ar_archive_writer v0.5.2)
 - #157668 (Add test for matches in `rustc_must_match_exhaustively`)

Failed merges:

 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Rollup of 17 pull requests

Successful merges:

 - #157166 (Change type of async context parameter after state transform.)
 - #157335 (bootstrap: Handle dotted table keys when parsing bootstrap.toml)
 - #157503 (Disable `tests/debuginfo/pretty-std.rs` `OsString` cdb check)
 - #157571 (Remove ProcMacro enum from proc macro ABI)
 - #148183 (rustdoc: Test & document `test_harness` code block attribute)
 - #153847 (Fix marker trait winnowing depending on impl order)
 - #156067 (Fix async drop glue for Box<T>)
 - #156399 (fix improper ctypes in Znext solver)
 - #157338 (Make `Literal::byte_character_value` work with bytes as well)
 - #157410 (Implement rustc_public::CrateDef{,Type} for FieldDef)
 - #157605 (Arg splat experiment - syntax impl)
 - #157630 (Add multibyte JSON diagnostic regression test)
 - #157633 (Reorder `impl` restriction rendering and add bottom margin)
 - #157642 (Report duplicate relaxed bounds during ast lowering)
 - #157652 (fix doc for unicode normalization faq on `casefold` APIs)
 - #157661 (Update to ar_archive_writer v0.5.2)
 - #157668 (Add test for matches in `rustc_must_match_exhaustively`)

Failed merges:

 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Rollup of 17 pull requests



Successful merges:

 - #157166 (Change type of async context parameter after state transform.)
 - #157335 (bootstrap: Handle dotted table keys when parsing bootstrap.toml)
 - #157503 (Disable `tests/debuginfo/pretty-std.rs` `OsString` cdb check)
 - #157571 (Remove ProcMacro enum from proc macro ABI)
 - #148183 (rustdoc: Test & document `test_harness` code block attribute)
 - #153847 (Fix marker trait winnowing depending on impl order)
 - #156067 (Fix async drop glue for Box<T>)
 - #156399 (fix improper ctypes in Znext solver)
 - #157338 (Make `Literal::byte_character_value` work with bytes as well)
 - #157410 (Implement rustc_public::CrateDef{,Type} for FieldDef)
 - #157605 (Arg splat experiment - syntax impl)
 - #157630 (Add multibyte JSON diagnostic regression test)
 - #157633 (Reorder `impl` restriction rendering and add bottom margin)
 - #157642 (Report duplicate relaxed bounds during ast lowering)
 - #157652 (fix doc for unicode normalization faq on `casefold` APIs)
 - #157661 (Update to ar_archive_writer v0.5.2)
 - #157668 (Add test for matches in `rustc_must_match_exhaustively`)

Failed merges:

 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Rollup of 17 pull requests



Successful merges:

 - #157166 (Change type of async context parameter after state transform.)
 - #157335 (bootstrap: Handle dotted table keys when parsing bootstrap.toml)
 - #157503 (Disable `tests/debuginfo/pretty-std.rs` `OsString` cdb check)
 - #157571 (Remove ProcMacro enum from proc macro ABI)
 - #148183 (rustdoc: Test & document `test_harness` code block attribute)
 - #153847 (Fix marker trait winnowing depending on impl order)
 - #156067 (Fix async drop glue for Box<T>)
 - #156399 (fix improper ctypes in Znext solver)
 - #157338 (Make `Literal::byte_character_value` work with bytes as well)
 - #157410 (Implement rustc_public::CrateDef{,Type} for FieldDef)
 - #157605 (Arg splat experiment - syntax impl)
 - #157630 (Add multibyte JSON diagnostic regression test)
 - #157633 (Reorder `impl` restriction rendering and add bottom margin)
 - #157642 (Report duplicate relaxed bounds during ast lowering)
 - #157652 (fix doc for unicode normalization faq on `casefold` APIs)
 - #157661 (Update to ar_archive_writer v0.5.2)
 - #157668 (Add test for matches in `rustc_must_match_exhaustively`)

Failed merges:

 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Rollup of 17 pull requests



Successful merges:

 - #157166 (Change type of async context parameter after state transform.)
 - #157335 (bootstrap: Handle dotted table keys when parsing bootstrap.toml)
 - #157503 (Disable `tests/debuginfo/pretty-std.rs` `OsString` cdb check)
 - #157571 (Remove ProcMacro enum from proc macro ABI)
 - #148183 (rustdoc: Test & document `test_harness` code block attribute)
 - #153847 (Fix marker trait winnowing depending on impl order)
 - #156067 (Fix async drop glue for Box<T>)
 - #156399 (fix improper ctypes in Znext solver)
 - #157338 (Make `Literal::byte_character_value` work with bytes as well)
 - #157410 (Implement rustc_public::CrateDef{,Type} for FieldDef)
 - #157605 (Arg splat experiment - syntax impl)
 - #157630 (Add multibyte JSON diagnostic regression test)
 - #157633 (Reorder `impl` restriction rendering and add bottom margin)
 - #157642 (Report duplicate relaxed bounds during ast lowering)
 - #157652 (fix doc for unicode normalization faq on `casefold` APIs)
 - #157661 (Update to ar_archive_writer v0.5.2)
 - #157668 (Add test for matches in `rustc_must_match_exhaustively`)

Failed merges:

 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
@rust-bors rust-bors Bot merged commit e295994 into rust-lang:main Jun 10, 2026
12 of 13 checks passed
@rustbot rustbot added this to the 1.98.0 milestone Jun 10, 2026
rust-timer added a commit that referenced this pull request Jun 10, 2026
Rollup merge of #157166 - cjgillot:retype-context-after, r=oli-obk

Change type of async context parameter after state transform.

`Future::poll` expects a `&mut std::task::Context<'_>`. Meanwhile, async coroutines use `std::future::ResumeTy` as resume parameter. This is meant to workaround the limitations of borrowck, which cannot prove that coroutines implement `for<'a, 'b> CoroutineTrait<&'a mut Context<'b>>`.

In the coroutine state transform, we need to change the signature from `ResumeTy` to the proper `&mut Context<'_>`. The current code attempts to find locals that have type `ResumeTy` to change their type. This is needlessly complex and relies on undocumented behaviour of the MIR builder.

Instead, this PR proposes to replace the `ResumeTy` argument with a new local, with value `ResumeTy(transmute(context))`.

Based on #156875.
@cjgillot cjgillot deleted the retype-context-after branch June 10, 2026 10:52
pull Bot pushed a commit to Kokoro2336/rust-analyzer that referenced this pull request Jun 11, 2026
Rollup of 17 pull requests



Successful merges:

 - rust-lang/rust#157166 (Change type of async context parameter after state transform.)
 - rust-lang/rust#157335 (bootstrap: Handle dotted table keys when parsing bootstrap.toml)
 - rust-lang/rust#157503 (Disable `tests/debuginfo/pretty-std.rs` `OsString` cdb check)
 - rust-lang/rust#157571 (Remove ProcMacro enum from proc macro ABI)
 - rust-lang/rust#148183 (rustdoc: Test & document `test_harness` code block attribute)
 - rust-lang/rust#153847 (Fix marker trait winnowing depending on impl order)
 - rust-lang/rust#156067 (Fix async drop glue for Box<T>)
 - rust-lang/rust#156399 (fix improper ctypes in Znext solver)
 - rust-lang/rust#157338 (Make `Literal::byte_character_value` work with bytes as well)
 - rust-lang/rust#157410 (Implement rustc_public::CrateDef{,Type} for FieldDef)
 - rust-lang/rust#157605 (Arg splat experiment - syntax impl)
 - rust-lang/rust#157630 (Add multibyte JSON diagnostic regression test)
 - rust-lang/rust#157633 (Reorder `impl` restriction rendering and add bottom margin)
 - rust-lang/rust#157642 (Report duplicate relaxed bounds during ast lowering)
 - rust-lang/rust#157652 (fix doc for unicode normalization faq on `casefold` APIs)
 - rust-lang/rust#157661 (Update to ar_archive_writer v0.5.2)
 - rust-lang/rust#157668 (Add test for matches in `rustc_must_match_exhaustively`)

Failed merges:

 - rust-lang/rust#157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
@JonathanBrouwer

Copy link
Copy Markdown
Contributor

@rust-timer build 0b580da

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (0b580da): comparison URL.

Overall result: ❌ regressions - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.6% [0.2%, 1.3%] 17
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Max RSS (memory usage)

This perf run didn't have relevant results for this metric.

Cycles

Results (secondary 2.7%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.7% [2.7%, 2.7%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Binary size

Results (primary 0.1%, secondary 3.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.1% [0.1%, 0.1%] 4
Regressions ❌
(secondary)
3.2% [0.4%, 5.5%] 14
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.1% [0.1%, 0.1%] 4

Bootstrap: 525.47s -> 517.162s (-1.58%)
Artifact size: 400.80 MiB -> 400.89 MiB (0.02%)

@rustbot rustbot added the perf-regression Performance regression. label Jun 13, 2026
@JonathanBrouwer

JonathanBrouwer commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Caused the perf regressions in #157683
Is there anything we can do about this?

rust-bors Bot pushed a commit that referenced this pull request Jun 14, 2026
Desugar async blocks in HIR instead of MIR



Implements MCP rust-lang/compiler-team#997
Based on #157166

In the current implementation, `gen`/`async`/`async gen` blocks and closures have type `Coroutine(..)` and `CoroutineClosure(..)`. Those types implement `Iterator`, `Future` or `AsyncIterator` depending on the initial desugaring.

This creates a lot of complexity:
- trait solvers must check which kind of coroutine each time;
- MIR StateTransform needs to fixup types depending on the coroutine kind.

I propose to change the desugaring for coroutines to:
- `gen { .. }` becomes `CoroutineIterator::from_coroutine(#[coroutine] { .. })`;
- `async { .. }` becomes `CoroutineFuture::from_coroutine(#[coroutine] { .. })`;
- `async gen { .. }` becomes `CoroutineAsyncIterator::from_coroutine(#[coroutine] { .. })`.

This way, all coroutines implement `std::ops::Coroutine` and `core` is responsible for translating this to user-friendly traits. All the complexity is pushed to error-reporting code, which is not soundness-critical.

Coroutine closures are a little more complex, as we need to keep the `CoroutineClosure` type for borrow-checking.

Main design point: I create two methods on `TyCtxt` that are meant to do the back-and-forth between wrapped and unwrapped coroutines. `coroutine_desugared_type` wraps a coroutine inside the adapter struct. `try_unwrap_desugared_coroutine` unwraps it.

r? @oli-obk 
cc @lcnr @RalfJung 
cc @estebank as I modify quite a lot of diagnostic code
rust-bors Bot pushed a commit that referenced this pull request Jun 14, 2026
Desugar async blocks in HIR instead of MIR



Implements MCP rust-lang/compiler-team#997
Based on #157166

In the current implementation, `gen`/`async`/`async gen` blocks and closures have type `Coroutine(..)` and `CoroutineClosure(..)`. Those types implement `Iterator`, `Future` or `AsyncIterator` depending on the initial desugaring.

This creates a lot of complexity:
- trait solvers must check which kind of coroutine each time;
- MIR StateTransform needs to fixup types depending on the coroutine kind.

I propose to change the desugaring for coroutines to:
- `gen { .. }` becomes `CoroutineIterator::from_coroutine(#[coroutine] { .. })`;
- `async { .. }` becomes `CoroutineFuture::from_coroutine(#[coroutine] { .. })`;
- `async gen { .. }` becomes `CoroutineAsyncIterator::from_coroutine(#[coroutine] { .. })`.

This way, all coroutines implement `std::ops::Coroutine` and `core` is responsible for translating this to user-friendly traits. All the complexity is pushed to error-reporting code, which is not soundness-critical.

Coroutine closures are a little more complex, as we need to keep the `CoroutineClosure` type for borrow-checking.

Main design point: I create two methods on `TyCtxt` that are meant to do the back-and-forth between wrapped and unwrapped coroutines. `coroutine_desugared_type` wraps a coroutine inside the adapter struct. `try_unwrap_desugared_coroutine` unwraps it.

r? @oli-obk 
cc @lcnr @RalfJung 
cc @estebank as I modify quite a lot of diagnostic code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

perf-regression Performance regression. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants