@@ -351,6 +351,10 @@ pub struct CoroutineClosureArgs<'tcx> {
351
351
pub args : GenericArgsRef < ' tcx > ,
352
352
}
353
353
354
+ /// See docs for explanation of how each argument is used.
355
+ ///
356
+ /// See [`CoroutineClosureSignature`] for how these arguments are put together
357
+ /// to make a callable [`FnSig`] suitable for typeck and borrowck.
354
358
pub struct CoroutineClosureArgsParts < ' tcx > {
355
359
/// This is the args of the typeck root.
356
360
pub parent_args : & ' tcx [ GenericArg < ' tcx > ] ,
@@ -485,25 +489,40 @@ pub struct CoroutineClosureSignature<'tcx> {
485
489
pub resume_ty : Ty < ' tcx > ,
486
490
pub yield_ty : Ty < ' tcx > ,
487
491
pub return_ty : Ty < ' tcx > ,
492
+
493
+ // Like the `fn_sig_as_fn_ptr_ty` of a regular closure, these types
494
+ // never actually differ. But we save them rather than recreating them
495
+ // from scratch just for good measure.
496
+ /// Always false
488
497
pub c_variadic : bool ,
498
+ /// Always [`hir::Unsafety::Normal`]
489
499
pub unsafety : hir:: Unsafety ,
500
+ /// Always [`abi::Abi::RustCall`]
490
501
pub abi : abi:: Abi ,
491
502
}
492
503
493
504
impl < ' tcx > CoroutineClosureSignature < ' tcx > {
505
+ /// Construct a coroutine from the closure signature. Since a coroutine signature
506
+ /// is agnostic to the type of generator that is returned (by-ref/by-move),
507
+ /// the caller must specify what "flavor" of generator that they'd like to
508
+ /// create. Additionally, they must manually compute the upvars of the closure.
509
+ ///
510
+ /// This helper is not really meant to be used directly except for early on
511
+ /// during typeck, when we want to put inference vars into the kind and upvars tys.
512
+ /// When the kind and upvars are known, use the other helper functions.
494
513
pub fn to_coroutine (
495
514
self ,
496
515
tcx : TyCtxt < ' tcx > ,
497
516
parent_args : & ' tcx [ GenericArg < ' tcx > ] ,
498
- kind_ty : Ty < ' tcx > ,
517
+ coroutine_kind_ty : Ty < ' tcx > ,
499
518
coroutine_def_id : DefId ,
500
519
tupled_upvars_ty : Ty < ' tcx > ,
501
520
) -> Ty < ' tcx > {
502
521
let coroutine_args = ty:: CoroutineArgs :: new (
503
522
tcx,
504
523
ty:: CoroutineArgsParts {
505
524
parent_args,
506
- kind_ty,
525
+ kind_ty : coroutine_kind_ty ,
507
526
resume_ty : self . resume_ty ,
508
527
yield_ty : self . yield_ty ,
509
528
return_ty : self . return_ty ,
@@ -515,19 +534,24 @@ impl<'tcx> CoroutineClosureSignature<'tcx> {
515
534
Ty :: new_coroutine ( tcx, coroutine_def_id, coroutine_args. args )
516
535
}
517
536
537
+ /// Given known upvars and a [`ClosureKind`](ty::ClosureKind), compute the coroutine
538
+ /// returned by that corresponding async fn trait.
539
+ ///
540
+ /// This function expects the upvars to have been computed already, and doesn't check
541
+ /// that the `ClosureKind` is actually supported by the coroutine-closure.
518
542
pub fn to_coroutine_given_kind_and_upvars (
519
543
self ,
520
544
tcx : TyCtxt < ' tcx > ,
521
545
parent_args : & ' tcx [ GenericArg < ' tcx > ] ,
522
546
coroutine_def_id : DefId ,
523
- closure_kind : ty:: ClosureKind ,
547
+ goal_kind : ty:: ClosureKind ,
524
548
env_region : ty:: Region < ' tcx > ,
525
549
closure_tupled_upvars_ty : Ty < ' tcx > ,
526
550
coroutine_captures_by_ref_ty : Ty < ' tcx > ,
527
551
) -> Ty < ' tcx > {
528
552
let tupled_upvars_ty = Self :: tupled_upvars_by_closure_kind (
529
553
tcx,
530
- closure_kind ,
554
+ goal_kind ,
531
555
self . tupled_inputs_ty ,
532
556
closure_tupled_upvars_ty,
533
557
coroutine_captures_by_ref_ty,
@@ -537,13 +561,21 @@ impl<'tcx> CoroutineClosureSignature<'tcx> {
537
561
self . to_coroutine (
538
562
tcx,
539
563
parent_args,
540
- Ty :: from_closure_kind ( tcx, closure_kind ) ,
564
+ Ty :: from_closure_kind ( tcx, goal_kind ) ,
541
565
coroutine_def_id,
542
566
tupled_upvars_ty,
543
567
)
544
568
}
545
569
546
- /// Given a closure kind, compute the tupled upvars that the given coroutine would return.
570
+ /// Compute the tupled upvars that a coroutine-closure's output coroutine
571
+ /// would return for the given `ClosureKind`.
572
+ ///
573
+ /// When `ClosureKind` is `FnMut`/`Fn`, then this will use the "captures by ref"
574
+ /// to return a set of upvars which are borrowed with the given `env_region`.
575
+ ///
576
+ /// This ensures that the `AsyncFn::call` will return a coroutine whose upvars'
577
+ /// lifetimes are related to the lifetime of the borrow on the closure made for
578
+ /// the call. This allows borrowck to enforce the self-borrows correctly.
547
579
pub fn tupled_upvars_by_closure_kind (
548
580
tcx : TyCtxt < ' tcx > ,
549
581
kind : ty:: ClosureKind ,
0 commit comments