@@ -101,6 +101,7 @@ use crate::{self as ty, Interner};
101101/// `yield` inside the coroutine.
102102/// * `GR`: The "return type", which is the type of value returned upon
103103/// completion of the coroutine.
104+ /// * `GW`: The "coroutine witness".
104105#[ derive_where( Clone , Copy , PartialEq , Eq , Hash , Debug ; I : Interner ) ]
105106#[ derive( TypeVisitable_Generic , TypeFoldable_Generic , Lift_Generic ) ]
106107pub struct ClosureArgs < I : Interner > {
@@ -238,6 +239,8 @@ pub struct CoroutineClosureArgsParts<I: Interner> {
238239 /// while the `tupled_upvars_ty`, representing the by-move version of the same
239240 /// captures, will be `(String,)`.
240241 pub coroutine_captures_by_ref_ty : I :: Ty ,
242+ /// Witness type returned by the generator produced by this coroutine-closure.
243+ pub coroutine_witness_ty : I :: Ty ,
241244}
242245
243246impl < I : Interner > CoroutineClosureArgs < I > {
@@ -248,6 +251,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
248251 parts. signature_parts_ty . into ( ) ,
249252 parts. tupled_upvars_ty . into ( ) ,
250253 parts. coroutine_captures_by_ref_ty . into ( ) ,
254+ parts. coroutine_witness_ty . into ( ) ,
251255 ] ) ) ,
252256 }
253257 }
@@ -288,6 +292,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
288292 }
289293
290294 pub fn coroutine_closure_sig ( self ) -> ty:: Binder < I , CoroutineClosureSignature < I > > {
295+ let interior = self . coroutine_witness_ty ( ) ;
291296 let ty:: FnPtr ( sig_tys, hdr) = self . signature_parts_ty ( ) . kind ( ) else { panic ! ( ) } ;
292297 sig_tys. map_bound ( |sig_tys| {
293298 let [ resume_ty, tupled_inputs_ty] = * sig_tys. inputs ( ) . as_slice ( ) else {
@@ -297,6 +302,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
297302 panic ! ( )
298303 } ;
299304 CoroutineClosureSignature {
305+ interior,
300306 tupled_inputs_ty,
301307 resume_ty,
302308 yield_ty,
@@ -312,6 +318,10 @@ impl<I: Interner> CoroutineClosureArgs<I> {
312318 self . split ( ) . coroutine_captures_by_ref_ty
313319 }
314320
321+ pub fn coroutine_witness_ty ( self ) -> I :: Ty {
322+ self . split ( ) . coroutine_witness_ty
323+ }
324+
315325 pub fn has_self_borrows ( & self ) -> bool {
316326 match self . coroutine_captures_by_ref_ty ( ) . kind ( ) {
317327 ty:: FnPtr ( sig_tys, _) => sig_tys
@@ -351,6 +361,7 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
351361#[ derive_where( Clone , Copy , PartialEq , Eq , Hash , Debug ; I : Interner ) ]
352362#[ derive( TypeVisitable_Generic , TypeFoldable_Generic ) ]
353363pub struct CoroutineClosureSignature < I : Interner > {
364+ pub interior : I :: Ty ,
354365 pub tupled_inputs_ty : I :: Ty ,
355366 pub resume_ty : I :: Ty ,
356367 pub yield_ty : I :: Ty ,
@@ -396,6 +407,7 @@ impl<I: Interner> CoroutineClosureSignature<I> {
396407 resume_ty : self . resume_ty ,
397408 yield_ty : self . yield_ty ,
398409 return_ty : self . return_ty ,
410+ witness : self . interior ,
399411 tupled_upvars_ty,
400412 } ,
401413 ) ;
@@ -575,6 +587,11 @@ pub struct CoroutineArgsParts<I: Interner> {
575587 pub yield_ty : I :: Ty ,
576588 pub return_ty : I :: Ty ,
577589
590+ /// The interior type of the coroutine.
591+ /// Represents all types that are stored in locals
592+ /// in the coroutine's body.
593+ pub witness : I :: Ty ,
594+
578595 /// The upvars captured by the closure. Remains an inference variable
579596 /// until the upvar analysis, which happens late in HIR typeck.
580597 pub tupled_upvars_ty : I :: Ty ,
@@ -590,6 +607,7 @@ impl<I: Interner> CoroutineArgs<I> {
590607 parts. resume_ty . into ( ) ,
591608 parts. yield_ty . into ( ) ,
592609 parts. return_ty . into ( ) ,
610+ parts. witness . into ( ) ,
593611 parts. tupled_upvars_ty . into ( ) ,
594612 ] ) ) ,
595613 }
@@ -611,6 +629,15 @@ impl<I: Interner> CoroutineArgs<I> {
611629 self . split ( ) . kind_ty
612630 }
613631
632+ /// This describes the types that can be contained in a coroutine.
633+ /// It will be a type variable initially and unified in the last stages of typeck of a body.
634+ /// It contains a tuple of all the types that could end up on a coroutine frame.
635+ /// The state transformation MIR pass may only produce layouts which mention types
636+ /// in this tuple. Upvars are not counted here.
637+ pub fn witness ( self ) -> I :: Ty {
638+ self . split ( ) . witness
639+ }
640+
614641 /// Returns an iterator over the list of types of captured paths by the coroutine.
615642 /// In case there was a type error in figuring out the types of the captured path, an
616643 /// empty iterator is returned.
0 commit comments