@@ -3495,46 +3495,8 @@ partial_apply
3495
3495
// %r will be of the substituted thick function type $(Z'...) -> R'
3496
3496
3497
3497
Creates a closure by partially applying the function ``%0 `` to a partial
3498
- sequence of its arguments. In the instruction syntax, the type of the callee is
3499
- specified after the argument list; the types of the argument and of the defined
3500
- value are derived from the function type of the callee. If the ``partial_apply ``
3501
- has an escaping function type (not ``[on_stack] ``) the closure context will be
3502
- allocated with retain count 1 and initialized to contain the values ``%1 ``,
3503
- ``%2 ``, etc. The closed-over values will not be retained; that must be done
3504
- separately before the ``partial_apply ``. The closure does however take ownership
3505
- of the partially applied arguments (except for ``@inout_aliasable `` parameters);
3506
- when the closure reference count reaches zero, the contained values will be
3507
- destroyed. If the ``partial_apply `` has a ``@noescape `` function type
3508
- (``partial_apply [on_stack] ``) the closure context is allocated on the stack and
3509
- initialized to contain the closed-over values. The closed-over values are not
3510
- retained, lifetime of the closed-over values must be managed separately. The
3511
- lifetime of the stack context of a ``partial_apply [on_stack] `` must be
3512
- terminated with a ``dealloc_stack ``.
3513
-
3514
- If the callee is generic, all of its generic parameters must be bound by the
3515
- given substitution list. The arguments are given with these generic
3516
- substitutions applied, and the resulting closure is of concrete function
3517
- type with the given substitutions applied. The generic parameters themselves
3518
- cannot be partially applied; all of them must be bound. The result is always
3519
- a concrete function.
3520
-
3521
- If an address argument has ``@inout_aliasable `` convention, the closure
3522
- obtained from ``partial_apply `` will not own its underlying value.
3523
- The ``@inout_aliasable `` parameter convention is used when a ``@noescape ``
3524
- closure captures an ``inout `` argument.
3525
-
3526
- TODO: The instruction, when applied to a generic function,
3527
- currently implicitly performs abstraction difference transformations enabled
3528
- by the given substitutions, such as promoting address-only arguments and returns
3529
- to register arguments. This should be fixed.
3530
-
3531
- By default, ``partial_apply `` creates a closure whose invocation takes ownership
3532
- of the context, meaning that a call implicitly releases the closure. The
3533
- ``[callee_guaranteed] `` change this to a caller-guaranteed model, where the
3534
- caller promises not to release the closure while the function is being called.
3535
-
3536
- This instruction is used to implement both curry thunks and closures. A
3537
- curried function in Swift::
3498
+ sequence of its arguments. This instruction is used to implement both curry
3499
+ thunks and closures. A curried function in Swift::
3538
3500
3539
3501
func foo(_ a:A)(b:B)(c:C)(d:D) -> E { /* body of foo */ }
3540
3502
@@ -3607,6 +3569,54 @@ lowers to an uncurried entry point and is curried in the enclosing function::
3607
3569
return %ret : $Int
3608
3570
}
3609
3571
3572
+ **Ownership Semantics of Closure Context during Invocation **: By default, an
3573
+ escaping ``partial_apply `` (``partial_apply `` without ``[on_stack]] `` creates a
3574
+ closure whose invocation takes ownership of the context, meaning that a call
3575
+ implicitly releases the closure. If the ``partial_apply `` is marked with the
3576
+ flag ``[callee_guaranteed] `` the invocation instead uses a caller-guaranteed
3577
+ model, where the caller promises not to release the closure while the function
3578
+ is being called.
3579
+
3580
+ **Captured Value Ownership Semantics **: In the instruction syntax, the type of
3581
+ the callee is specified after the argument list; the types of the argument and
3582
+ of the defined value are derived from the function type of the callee. Even so,
3583
+ the ownership requirements of the partial apply are not the same as that of the
3584
+ callee function (and thus said signature). Instead:
3585
+
3586
+ 1. If the ``partial_apply `` has a ``@noescape `` function type (``partial_apply
3587
+ [on_stack] ``) the closure context is allocated on the stack and is
3588
+ initialized to contain the closed-over values without taking ownership of
3589
+ those values. The closed-over values are not retained and the lifetime of the
3590
+ closed-over values must be managed by other instruction independently of the
3591
+ ``partial_apply ``. The lifetime of the stack context of a ``partial_apply
3592
+ [on_stack] `` must be terminated with a ``dealloc_stack ``.
3593
+
3594
+ 2. If the ``partial_apply `` has an escaping function type (not ``[on_stack] ``)
3595
+ then the closure context will be heap allocated with a retain count of 1. Any
3596
+ closed over parameters (except for ``@inout `` parameters) will be consumed by
3597
+ the partial_apply. This ensures that no matter when the ``partial_apply `` is
3598
+ called, the captured arguments are alive. When the closure context's
3599
+ reference count reaches zero, the contained values are destroyed. If the
3600
+ callee requires an owned parameter, then the implicit partial_apply forwarder
3601
+ created by IRGen will copy the underlying argument and pass it to the callee.
3602
+
3603
+ 3. If an address argument has ``@inout_aliasable `` convention, the closure
3604
+ obtained from ``partial_apply `` will not own its underlying value. The
3605
+ ``@inout_aliasable `` parameter convention is used when a ``@noescape ``
3606
+ closure captures an ``inout `` argument.
3607
+
3608
+ **NOTE: ** If the callee is generic, all of its generic parameters must be bound
3609
+ by the given substitution list. The arguments are given with these generic
3610
+ substitutions applied, and the resulting closure is of concrete function type
3611
+ with the given substitutions applied. The generic parameters themselves cannot
3612
+ be partially applied; all of them must be bound. The result is always a concrete
3613
+ function.
3614
+
3615
+ **TODO: ** The instruction, when applied to a generic function, currently
3616
+ implicitly performs abstraction difference transformations enabled by the given
3617
+ substitutions, such as promoting address-only arguments and returns to register
3618
+ arguments. This should be fixed.
3619
+
3610
3620
builtin
3611
3621
```````
3612
3622
::
0 commit comments