Skip to content

[WIP] Make assoc item Coroutine::Yield a lending GAT -> Yield<'a>. - #163907

Open
LorrensP-2158466 wants to merge 2 commits into
rust-lang:mainfrom
LorrensP-2158466:gat-coroutine-yield
Open

LorrensP-2158466 wants to merge 2 commits into
rust-lang:mainfrom
LorrensP-2158466:gat-coroutine-yield

Conversation

@LorrensP-2158466

@LorrensP-2158466 LorrensP-2158466 commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Attempts to implement #69268. related zulip discussion: #t-types/call-for-participation > looking for help with generalizing coroutine trait

PR makes the Yield assoc item of Coroutine a GAT by using a lifetime, making it possible to return borrows from inside of the coroutine:

pub trait Coroutine<R = ()> {
  type Yield<'a>
  where
      Self: 'a;
  type Return;
  
fn resume<'a>(self: Pin<&'a mut Self>, arg: R) -> CoroutineState<Self::Yield<'a>, Self::Return>;

Work in progress of course.

r? @oli-obk

@rustbot

rustbot commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_ir

cc @jdonszelmann, @JonathanBrouwer

@rustbot rustbot added the A-attributes Area: Attributes (`#[…]`, `#![…]`) label Oct 6, 2026
@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. T-libs Relevant to the library team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Oct 6, 2026
Comment on lines +954 to +970
} else if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::CoroutineYield) {
(
coroutine.yield_ty().into(),
ty::AliasTerm::new(
ecx.cx(),
goal.predicate.alias.kind,
[
self_ty.into(),
coroutine.resume_ty().into(),
goal.predicate
.alias
.args
.iter()
.filter(|a| a.as_region().is_some())
.next()
.unwrap(),
],

@LorrensP-2158466 LorrensP-2158466 Oct 6, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have absolutely no idea if this is how I insert that lifetime. but its the only way i could make it work.

if its correct, there is probably a nicer way :D

View changes since the review

@LorrensP-2158466

Copy link
Copy Markdown
Contributor Author

So with the tests, i mostly got away with usign HRTBs for the yield lifetimes. but some use stucts that borrow from self and return a coroutine, some of these i could not handle...

and ofcourse the dyn Coroutine<...> thing not working.

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job test-x86_64-gnu-llvm-22 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

---- [mir-opt] tests/mir-opt/inline/inline_coroutine.rs stdout ----
------rustc stdout------------------------------

------rustc stderr------------------------------
error[E0716]: temporary value dropped while borrowed
##[error]  --> /checkout/tests/mir-opt/inline/inline_coroutine.rs:13:28
   |
13 |     let _r = Pin::new(&mut g()).resume(false);
   |                            ^^^               - temporary value is freed at the end of this statement
   |                            |
   |                            creates a temporary value which is freed while still in use
14 | }
   | - borrow might be used here, when `_r` is dropped and runs the destructor for type `CoroutineState<<impl Coroutine<bool> as Coroutine<bool>>::Yield<'_>, <impl Coroutine<bool> as Coroutine<bool>>::Return>`
   |
help: consider using a `let` binding to create a longer lived value
   |
13 ~     let mut binding = g();
14 ~     let _r = Pin::new(&mut binding).resume(false);
   |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0716`.

------------------------------------------

error: compilation failed!
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/mir-opt/inline/inline_coroutine.rs" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=i686-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "-O" "-Copt-level=1" "-Zdump-mir=Inline" "-Zvalidate-mir" "-Zlint-mir" "-Zdump-mir-exclude-pass-number" "-Zmir-include-spans=false" "--crate-type=rlib" "-Zmir-opt-level=4" "-Zmir-enable-passes=+ReorderBasicBlocks,+ReorderLocals" "-Zdump-mir-dir=/checkout/obj/build/x86_64-unknown-linux-gnu/test/mir-opt/inline/inline_coroutine" "--emit" "mir" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/mir-opt/inline/inline_coroutine" "-Znext-solver=coherence" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "--edition=2015" "-Zinline-mir-hint-threshold=1000" "-C" "debuginfo=full"
stdout: none
--- stderr -------------------------------
error[E0716]: temporary value dropped while borrowed
##[error]  --> /checkout/tests/mir-opt/inline/inline_coroutine.rs:13:28
   |
13 |     let _r = Pin::new(&mut g()).resume(false);
   |                            ^^^               - temporary value is freed at the end of this statement
   |                            |
   |                            creates a temporary value which is freed while still in use
14 | }
   | - borrow might be used here, when `_r` is dropped and runs the destructor for type `CoroutineState<<impl Coroutine<bool> as Coroutine<bool>>::Yield<'_>, <impl Coroutine<bool> as Coroutine<bool>>::Return>`
   |
help: consider using a `let` binding to create a longer lived value
   |
13 ~     let mut binding = g();
14 ~     let _r = Pin::new(&mut binding).resume(false);
   |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0716`.

@oli-obk oli-obk added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 23, 2026
@oli-obk

oli-obk commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

as discussed on zulip, let's add the lifetime to the trait instead of the GAT while GATs are still a bit undersupported

@rust-bors

rust-bors Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #165493) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants