You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: proposals/NNNN-nonisolated-for-global-actor-cutoff.md
+37-6Lines changed: 37 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -163,11 +163,36 @@ For global-actor-isolated value types, [SE-0434: Usability of global-actor-isola
163
163
164
164
```swift
165
165
structS {
166
-
nonisolatedvar x: Int// okay
166
+
var x: Int=0// okay ('nonisolated' is inferred within the module)
167
+
}
168
+
169
+
actorMyActor {
170
+
functest(s: S) {
171
+
print(s.x) // synchronous access to 'x' after sending `S` to `MyActor` is okay.
172
+
}
167
173
}
168
174
```
169
175
170
-
In the above code, the value type `S` is implicitly `Sendable` because its storage `x` is of `Sendable` type `Int`. When `Sendable` value types are passed between isolation domains, each isolation domain has an independent copy of the value. Accessing stored properties of a value type from across isolation domains is safe as long as the stored property type is also `Sendable`. Even if the stored property is a `var`, assigning to the property will not risk a data race, because the assignment cannot have effects on copies in other isolation domains. Therefore, synchronized access to `x` in the example above is safe.
176
+
In the above code, the value type `S` is implicitly `Sendable` within the module and its storage `x` is of `Sendable` type `Int`. When `Sendable` value types are passed between isolation domains, each isolation domain has an independent copy of the value. Accessing properties stored on a value type from across isolation domains is safe as long as the stored property type is also `Sendable`. Even if the stored property is a `var`, assigning to the property will not risk a data race, because the assignment cannot have effects on copies in other isolation domains. Therefore, synchronous access of `x` from within the module is okay.
177
+
178
+
Additionally, [SE-0434](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0434-global-actor-isolated-types-usability.md) allows explicitly annotating globally-isolated value types' properties such as `x` in the previous example with `nonisolated` for synchronous access from outside the module. This proposal extends this rule to **all**`Sendable` value types:
179
+
180
+
```swift
181
+
// In Module A
182
+
publicstructS: Sendable {
183
+
nonisolatedpublicvar x: Int=0// okay
184
+
publicinit() {}
185
+
}
186
+
187
+
// In Module B
188
+
importA
189
+
190
+
actorMyActor {
191
+
functest(s: S) {
192
+
print(s.x) // synchronous access to 'x' after sending `S` to `MyActor` is okay.
193
+
}
194
+
}
195
+
```
171
196
172
197
### 5. Classes, structs, and enums
173
198
@@ -224,23 +249,27 @@ The above behavior is semantically consistent with the existing rules around glo
224
249
225
250
Additionally, we propose the following set of rules for when the `nonisolated` attribute **cannot** be applied:
226
251
227
-
* Along with some other isolation such as a global actor or an isolated parameter:
252
+
####Along with some other isolation such as a global actor or an isolated parameter:
228
253
229
254
```swift
230
255
@MainActor
231
256
nonisolatedstructConflict {} // error: 'struct 'Conflict' has multiple actor-isolation attributes ('nonisolated' and 'MainActor')'
232
257
```
233
258
234
-
* On a property of a `Sendable` type when the type of the property does not conform to `Sendable`:
259
+
The above code is invalid because the `Conflict` struct cannot simultaneously opt-out of isolation and declare one.
260
+
261
+
#### On a property of a `Sendable` type when the type of the property does not conform to `Sendable`:
235
262
236
263
```swift
237
264
@MainActor
238
265
structInvalidStruct/* implicitly Sendable */ {
239
-
nonisolatedlettest: NonSendable // error: 'nonisolated' can not be applied to variable with non-'Sendable' type 'NonSendable
266
+
nonisolatedletx: NonSendable // error: 'nonisolated' can not be applied to variable with non-'Sendable' type 'NonSendable
240
267
}
241
268
```
242
269
243
-
* On a property of a `Sendable` class when the property is a var:
270
+
In the above code, `InvalidStruct` is `Sendable`, allowing it to be sent across the concurrency domains. The property `x` is of `NonSendable` type, and if declared `nonisolated`, it would be allowed to be accessed from outside the main actor domain that `InvalidStruct` is isolated to, thus contradicting its lack of `Sendable` capability.
271
+
272
+
#### On a property of a `Sendable` class when the property is a var:
244
273
245
274
```swift
246
275
@MainActor
@@ -249,6 +278,8 @@ final class InvalidClass /* implicitly Sendable */ {
249
278
}
250
279
```
251
280
281
+
In this example, `InvalidClass` is a `Sendable` reference type, which allows concurrent synchronous access to `test` since it is `nonisolated`. This introduces a potential data race.
282
+
252
283
## Source compatibility
253
284
254
285
None, this is an additive change to the concurrency model.
0 commit comments