13
13
14
14
This proposal extends region isolation to enable an explicit ` transferring `
15
15
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.
18
19
19
20
## Motivation
20
21
@@ -37,9 +38,13 @@ func tryTransfer(ns: NonSendable) async {
37
38
}
38
39
```
39
40
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:
43
48
44
49
``` swift
45
50
class NonSendable {}
@@ -123,12 +128,14 @@ data-race safety diagnostics, even under `-strict-concurrency=complete`.
123
128
124
129
Requiring ` Sendable ` on the parameter type of ` resume(returning:) ` is a harsh
125
130
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:) ` .
127
133
128
134
## Proposed solution
129
135
130
136
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:
132
139
133
140
``` swift
134
141
public struct CheckedContinuation <T , E : Error >: Sendable {
@@ -192,8 +199,12 @@ is in a disconnected region, enabling non-`Sendable` result values to cross an
192
199
actor isolation boundary:
193
200
194
201
``` swift
202
+ @MainActor func onMain (_ : NonSendable) { ... }
203
+
195
204
nonisolated func f (s : S) async {
196
205
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
197
208
}
198
209
```
199
210
@@ -284,9 +295,17 @@ struct Y2: P1 {
284
295
285
296
When a call passes an argument to a ` transferring ` parameter, the caller cannot
286
297
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.
290
309
291
310
## Source compatibility
292
311
0 commit comments