Skip to content

Commit d3329d7

Browse files
committed
Address editorial review feedback.
1 parent a39c3fb commit d3329d7

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

proposals/NNNN-transferring-parameters-and-results.md

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313

1414
This proposal extends region isolation to enable an explicit `transferring`
1515
annotation to denote when a parameter or result value is required to be in a
16-
disconnected region, allowing the callee or the caller, respectively, to
17-
transfer a non-`Sendable` parameter or result value over an isolation boundary.
16+
disconnected region at the function boundary. This allows the callee or the
17+
caller, respectively, to transfer a non-`Sendable` parameter or result value
18+
over an isolation boundary or merge the value into an actor-isolated region.
1819

1920
## Motivation
2021

@@ -37,9 +38,13 @@ func tryTransfer(ns: NonSendable) async {
3738
}
3839
```
3940

40-
However, for actor initializers, parameters are always considered to be
41-
transferred into the actor's region, because initializer parameters are
42-
typically used to initialize actor-isolated state:
41+
Actor initializers have a special rule that allows transferring its parameter
42+
values into the actor-isolated region. Actor initializers are `nonisolated`, so
43+
a call to an actor initializer does not cross an isolation boundary, meaning
44+
the argument values would be usable in the caller after the initializer returns
45+
under the standard region isolation rules. SE-0414 consider actor initializer
46+
parameters as being transferred into the actor's region to allow initializing
47+
actor-isolated state with those values:
4348

4449
```swift
4550
class NonSendable {}
@@ -123,12 +128,14 @@ data-race safety diagnostics, even under `-strict-concurrency=complete`.
123128

124129
Requiring `Sendable` on the parameter type of `resume(returning:)` is a harsh
125130
restriction, and it's safe to pass a non-`Sendable` value as long as the value
126-
is in a disconnected region.
131+
is in a disconnected region and all values in that disconnected region are not
132+
used again after the call to `resume(returning:)`.
127133

128134
## Proposed solution
129135

130136
This proposal enables explicitly specifying parameter and result values as
131-
being transferred over an isolation boundary using a modifier:
137+
being transferred over an isolation boundary using a contextual `transferring`
138+
modifier:
132139

133140
```swift
134141
public struct CheckedContinuation<T, E: Error>: Sendable {
@@ -192,8 +199,12 @@ is in a disconnected region, enabling non-`Sendable` result values to cross an
192199
actor isolation boundary:
193200

194201
```swift
202+
@MainActor func onMain(_: NonSendable) { ... }
203+
195204
nonisolated func f(s: S) async {
196205
let ns = s.getNonSendable() // okay; 'ns' is in a disconnected region
206+
207+
await onMain(ns) // 'ns' can be transferred away to the main actor
197208
}
198209
```
199210

@@ -284,9 +295,17 @@ struct Y2: P1 {
284295

285296
When a call passes an argument to a `transferring` parameter, the caller cannot
286297
use the argument value again after the callee returns. By default `transferring`
287-
on a function parameter implies that the callee consumes the parameter, but it does
288-
not imply no implicit copying semantics. `transferring` may also be used with an
289-
explicit `consuming` or `borrowing` ownership modifier.
298+
on a function parameter implies that the callee consumes the parameter. Like
299+
`consuming` parameters, a `transferring` parameter can be re-assigned inside
300+
the callee. Unlike `consuming` parameters, `transferring` parameters do not
301+
have no-implicit-copying semantics.
302+
303+
To opt into no-implicit-copying semantics or to change the default ownership
304+
convention, `transferring` may also be used with an explicit `consuming` or
305+
`borrowing` ownership modifier. Note that an explicit `borrowing` annotation
306+
always implies no-implicit-copying, so there is no way to change the default
307+
ownership convention of a `transferring` parameter without also opting into
308+
no-implicit-copying semantics.
290309

291310
## Source compatibility
292311

0 commit comments

Comments
 (0)