@@ -101,6 +101,7 @@ use crate::{self as ty, Interner};
101
101
/// `yield` inside the coroutine.
102
102
/// * `GR`: The "return type", which is the type of value returned upon
103
103
/// completion of the coroutine.
104
+ /// * `GW`: The "coroutine witness".
104
105
#[ derive_where( Clone , Copy , PartialEq , Eq , Hash , Debug ; I : Interner ) ]
105
106
#[ derive( TypeVisitable_Generic , TypeFoldable_Generic , Lift_Generic ) ]
106
107
pub struct ClosureArgs < I : Interner > {
@@ -238,6 +239,8 @@ pub struct CoroutineClosureArgsParts<I: Interner> {
238
239
/// while the `tupled_upvars_ty`, representing the by-move version of the same
239
240
/// captures, will be `(String,)`.
240
241
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 ,
241
244
}
242
245
243
246
impl < I : Interner > CoroutineClosureArgs < I > {
@@ -248,6 +251,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
248
251
parts. signature_parts_ty . into ( ) ,
249
252
parts. tupled_upvars_ty . into ( ) ,
250
253
parts. coroutine_captures_by_ref_ty . into ( ) ,
254
+ parts. coroutine_witness_ty . into ( ) ,
251
255
] ) ) ,
252
256
}
253
257
}
@@ -288,6 +292,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
288
292
}
289
293
290
294
pub fn coroutine_closure_sig ( self ) -> ty:: Binder < I , CoroutineClosureSignature < I > > {
295
+ let interior = self . coroutine_witness_ty ( ) ;
291
296
let ty:: FnPtr ( sig_tys, hdr) = self . signature_parts_ty ( ) . kind ( ) else { panic ! ( ) } ;
292
297
sig_tys. map_bound ( |sig_tys| {
293
298
let [ resume_ty, tupled_inputs_ty] = * sig_tys. inputs ( ) . as_slice ( ) else {
@@ -297,6 +302,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
297
302
panic ! ( )
298
303
} ;
299
304
CoroutineClosureSignature {
305
+ interior,
300
306
tupled_inputs_ty,
301
307
resume_ty,
302
308
yield_ty,
@@ -312,6 +318,10 @@ impl<I: Interner> CoroutineClosureArgs<I> {
312
318
self . split ( ) . coroutine_captures_by_ref_ty
313
319
}
314
320
321
+ pub fn coroutine_witness_ty ( self ) -> I :: Ty {
322
+ self . split ( ) . coroutine_witness_ty
323
+ }
324
+
315
325
pub fn has_self_borrows ( & self ) -> bool {
316
326
match self . coroutine_captures_by_ref_ty ( ) . kind ( ) {
317
327
ty:: FnPtr ( sig_tys, _) => sig_tys
@@ -351,6 +361,7 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
351
361
#[ derive_where( Clone , Copy , PartialEq , Eq , Hash , Debug ; I : Interner ) ]
352
362
#[ derive( TypeVisitable_Generic , TypeFoldable_Generic ) ]
353
363
pub struct CoroutineClosureSignature < I : Interner > {
364
+ pub interior : I :: Ty ,
354
365
pub tupled_inputs_ty : I :: Ty ,
355
366
pub resume_ty : I :: Ty ,
356
367
pub yield_ty : I :: Ty ,
@@ -396,6 +407,7 @@ impl<I: Interner> CoroutineClosureSignature<I> {
396
407
resume_ty : self . resume_ty ,
397
408
yield_ty : self . yield_ty ,
398
409
return_ty : self . return_ty ,
410
+ witness : self . interior ,
399
411
tupled_upvars_ty,
400
412
} ,
401
413
) ;
@@ -575,6 +587,11 @@ pub struct CoroutineArgsParts<I: Interner> {
575
587
pub yield_ty : I :: Ty ,
576
588
pub return_ty : I :: Ty ,
577
589
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
+
578
595
/// The upvars captured by the closure. Remains an inference variable
579
596
/// until the upvar analysis, which happens late in HIR typeck.
580
597
pub tupled_upvars_ty : I :: Ty ,
@@ -590,6 +607,7 @@ impl<I: Interner> CoroutineArgs<I> {
590
607
parts. resume_ty . into ( ) ,
591
608
parts. yield_ty . into ( ) ,
592
609
parts. return_ty . into ( ) ,
610
+ parts. witness . into ( ) ,
593
611
parts. tupled_upvars_ty . into ( ) ,
594
612
] ) ) ,
595
613
}
@@ -611,6 +629,15 @@ impl<I: Interner> CoroutineArgs<I> {
611
629
self . split ( ) . kind_ty
612
630
}
613
631
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
+
614
641
/// Returns an iterator over the list of types of captured paths by the coroutine.
615
642
/// In case there was a type error in figuring out the types of the captured path, an
616
643
/// empty iterator is returned.
0 commit comments