@@ -275,6 +275,10 @@ pub struct CoroutineClosureArgs<'tcx> {
275
275
pub args : GenericArgsRef < ' tcx > ,
276
276
}
277
277
278
+ /// See docs for explanation of how each argument is used.
279
+ ///
280
+ /// See [`CoroutineClosureSignature`] for how these arguments are put together
281
+ /// to make a callable [`FnSig`] suitable for typeck and borrowck.
278
282
pub struct CoroutineClosureArgsParts < ' tcx > {
279
283
/// This is the args of the typeck root.
280
284
pub parent_args : & ' tcx [ GenericArg < ' tcx > ] ,
@@ -409,25 +413,40 @@ pub struct CoroutineClosureSignature<'tcx> {
409
413
pub resume_ty : Ty < ' tcx > ,
410
414
pub yield_ty : Ty < ' tcx > ,
411
415
pub return_ty : Ty < ' tcx > ,
416
+
417
+ // Like the `fn_sig_as_fn_ptr_ty` of a regular closure, these types
418
+ // never actually differ. But we save them rather than recreating them
419
+ // from scratch just for good measure.
420
+ /// Always false
412
421
pub c_variadic : bool ,
422
+ /// Always [`hir::Unsafety::Normal`]
413
423
pub unsafety : hir:: Unsafety ,
424
+ /// Always [`abi::Abi::RustCall`]
414
425
pub abi : abi:: Abi ,
415
426
}
416
427
417
428
impl < ' tcx > CoroutineClosureSignature < ' tcx > {
429
+ /// Construct a coroutine from the closure signature. Since a coroutine signature
430
+ /// is agnostic to the type of generator that is returned (by-ref/by-move),
431
+ /// the caller must specify what "flavor" of generator that they'd like to
432
+ /// create. Additionally, they must manually compute the upvars of the closure.
433
+ ///
434
+ /// This helper is not really meant to be used directly except for early on
435
+ /// during typeck, when we want to put inference vars into the kind and upvars tys.
436
+ /// When the kind and upvars are known, use the other helper functions.
418
437
pub fn to_coroutine (
419
438
self ,
420
439
tcx : TyCtxt < ' tcx > ,
421
440
parent_args : & ' tcx [ GenericArg < ' tcx > ] ,
422
- kind_ty : Ty < ' tcx > ,
441
+ coroutine_kind_ty : Ty < ' tcx > ,
423
442
coroutine_def_id : DefId ,
424
443
tupled_upvars_ty : Ty < ' tcx > ,
425
444
) -> Ty < ' tcx > {
426
445
let coroutine_args = ty:: CoroutineArgs :: new (
427
446
tcx,
428
447
ty:: CoroutineArgsParts {
429
448
parent_args,
430
- kind_ty,
449
+ kind_ty : coroutine_kind_ty ,
431
450
resume_ty : self . resume_ty ,
432
451
yield_ty : self . yield_ty ,
433
452
return_ty : self . return_ty ,
@@ -439,19 +458,24 @@ impl<'tcx> CoroutineClosureSignature<'tcx> {
439
458
Ty :: new_coroutine ( tcx, coroutine_def_id, coroutine_args. args )
440
459
}
441
460
461
+ /// Given known upvars and a [`ClosureKind`](ty::ClosureKind), compute the coroutine
462
+ /// returned by that corresponding async fn trait.
463
+ ///
464
+ /// This function expects the upvars to have been computed already, and doesn't check
465
+ /// that the `ClosureKind` is actually supported by the coroutine-closure.
442
466
pub fn to_coroutine_given_kind_and_upvars (
443
467
self ,
444
468
tcx : TyCtxt < ' tcx > ,
445
469
parent_args : & ' tcx [ GenericArg < ' tcx > ] ,
446
470
coroutine_def_id : DefId ,
447
- closure_kind : ty:: ClosureKind ,
471
+ goal_kind : ty:: ClosureKind ,
448
472
env_region : ty:: Region < ' tcx > ,
449
473
closure_tupled_upvars_ty : Ty < ' tcx > ,
450
474
coroutine_captures_by_ref_ty : Ty < ' tcx > ,
451
475
) -> Ty < ' tcx > {
452
476
let tupled_upvars_ty = Self :: tupled_upvars_by_closure_kind (
453
477
tcx,
454
- closure_kind ,
478
+ goal_kind ,
455
479
self . tupled_inputs_ty ,
456
480
closure_tupled_upvars_ty,
457
481
coroutine_captures_by_ref_ty,
@@ -461,13 +485,21 @@ impl<'tcx> CoroutineClosureSignature<'tcx> {
461
485
self . to_coroutine (
462
486
tcx,
463
487
parent_args,
464
- Ty :: from_closure_kind ( tcx, closure_kind ) ,
488
+ Ty :: from_closure_kind ( tcx, goal_kind ) ,
465
489
coroutine_def_id,
466
490
tupled_upvars_ty,
467
491
)
468
492
}
469
493
470
- /// Given a closure kind, compute the tupled upvars that the given coroutine would return.
494
+ /// Compute the tupled upvars that a coroutine-closure's output coroutine
495
+ /// would return for the given `ClosureKind`.
496
+ ///
497
+ /// When `ClosureKind` is `FnMut`/`Fn`, then this will use the "captures by ref"
498
+ /// to return a set of upvars which are borrowed with the given `env_region`.
499
+ ///
500
+ /// This ensures that the `AsyncFn::call` will return a coroutine whose upvars'
501
+ /// lifetimes are related to the lifetime of the borrow on the closure made for
502
+ /// the call. This allows borrowck to enforce the self-borrows correctly.
471
503
pub fn tupled_upvars_by_closure_kind (
472
504
tcx : TyCtxt < ' tcx > ,
473
505
kind : ty:: ClosureKind ,
0 commit comments