Skip to content

Commit 2514d13

Browse files
committed
Reword and clarify per feedback.
1 parent 1bfd491 commit 2514d13

File tree

1 file changed

+37
-6
lines changed

1 file changed

+37
-6
lines changed

proposals/NNNN-nonisolated-for-global-actor-cutoff.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,36 @@ For global-actor-isolated value types, [SE-0434: Usability of global-actor-isola
163163

164164
```swift
165165
struct S {
166-
nonisolated var x: Int // okay
166+
var x: Int = 0 // okay ('nonisolated' is inferred within the module)
167+
}
168+
169+
actor MyActor {
170+
func test(s: S) {
171+
print(s.x) // synchronous access to 'x' after sending `S` to `MyActor` is okay.
172+
}
167173
}
168174
```
169175

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+
public struct S: Sendable {
183+
nonisolated public var x: Int = 0 // okay
184+
public init() {}
185+
}
186+
187+
// In Module B
188+
import A
189+
190+
actor MyActor {
191+
func test(s: S) {
192+
print(s.x) // synchronous access to 'x' after sending `S` to `MyActor` is okay.
193+
}
194+
}
195+
```
171196

172197
### 5. Classes, structs, and enums
173198

@@ -224,23 +249,27 @@ The above behavior is semantically consistent with the existing rules around glo
224249

225250
Additionally, we propose the following set of rules for when the `nonisolated` attribute **cannot** be applied:
226251

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:
228253

229254
```swift
230255
@MainActor
231256
nonisolated struct Conflict {} // error: 'struct 'Conflict' has multiple actor-isolation attributes ('nonisolated' and 'MainActor')'
232257
```
233258

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`:
235262

236263
```swift
237264
@MainActor
238265
struct InvalidStruct /* implicitly Sendable */ {
239-
nonisolated let test: NonSendable // error: 'nonisolated' can not be applied to variable with non-'Sendable' type 'NonSendable
266+
nonisolated let x: NonSendable // error: 'nonisolated' can not be applied to variable with non-'Sendable' type 'NonSendable
240267
}
241268
```
242269

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:
244273

245274
```swift
246275
@MainActor
@@ -249,6 +278,8 @@ final class InvalidClass /* implicitly Sendable */ {
249278
}
250279
```
251280

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+
252283
## Source compatibility
253284

254285
None, this is an additive change to the concurrency model.

0 commit comments

Comments
 (0)