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
[SE-0470] Ensure that one cannot form an isolated conformance when Self: Sendable
While here, fix some issues around implied isolated conformances (we
could get into an inconsistent state). Also provide an educational
note discussing isolated conformances and the kinds of errors one can
see when they are used from outside of their isolation domain.
// expected-error@+2{{type 'PSendableS' does not conform to protocol 'PSendable'}}
97
+
// expected-error@+1{{main actor-isolated conformance of 'PSendableS' to 'P' cannot satisfy conformance requirement for a 'Sendable' type parameter 'Self'}}
@@ -108,8 +116,8 @@ struct PSendableMetaWrapper<T: P & SendableMetatype>: P {
108
116
@MainActor
109
117
func testIsolationConformancesInTypes(){
110
118
typealiasA1=PWrapper<C>
111
-
typealiasA2=PSendableWrapper<C> // expected-error{{isolated conformance of 'C' to 'P' cannot satisfy conformance requirement for a `Sendable` type parameter 'T'}}
112
-
typealiasA3=PSendableMetaWrapper<C> // expected-error{{isolated conformance of 'C' to 'P' cannot satisfy conformance requirement for a `SendableMetatype` type parameter 'T'}}
119
+
typealiasA2=PSendableWrapper<C> // expected-error{{isolated conformance of 'C' to 'P' cannot satisfy conformance requirement for a 'Sendable' type parameter 'T'}}
120
+
typealiasA3=PSendableMetaWrapper<C> // expected-error{{isolated conformance of 'C' to 'P' cannot satisfy conformance requirement for a 'SendableMetatype' type parameter 'T'}}
acceptSendableP(c) // expected-error{{main actor-isolated conformance of 'C' to 'P' cannot satisfy conformance requirement for a `Sendable` type parameter}}
128
-
acceptSendableMetaP(c) // expected-error{{isolated conformance of 'C' to 'P' cannot satisfy conformance requirement for a `Sendable` type parameter}}
135
+
acceptSendableP(c) // expected-error{{main actor-isolated conformance of 'C' to 'P' cannot satisfy conformance requirement for a 'Sendable' type parameter}}
136
+
acceptSendableMetaP(c) // expected-error{{isolated conformance of 'C' to 'P' cannot satisfy conformance requirement for a 'Sendable' type parameter}}
acceptSendableMetaP(a) // expected-error{{main actor-isolated conformance of 'SomeActor' to 'P' cannot satisfy conformance requirement for a `Sendable` type parameter}}
142
+
acceptSendableMetaP(a) // expected-error{{main actor-isolated conformance of 'SomeActor' to 'P' cannot satisfy conformance requirement for a 'Sendable' type parameter}}
acceptSendableMetaP(c) // expected-error{{global actor 'SomeGlobalActor'-isolated conformance of 'CMismatchedIsolation' to 'P' cannot satisfy conformance requirement for a `Sendable` type parameter}}
148
+
acceptSendableMetaP(c) // expected-error{{global actor 'SomeGlobalActor'-isolated conformance of 'CMismatchedIsolation' to 'P' cannot satisfy conformance requirement for a 'Sendable' type parameter}}
Copy file name to clipboardExpand all lines: userdocs/diagnostics/conformance-isolation.md
+19-19Lines changed: 19 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,26 +29,26 @@ This code will produce an error similar to:
29
29
30
30
There are several options for resolving this error, as indicated by the notes:
31
31
32
-
* If all of the operations used to satisfy the protocol's requirements are on the same global actor (such as the main actor), the conformance itself can be isolated to that global actor. This allows the conformance to be used inside code running on that actor, but it cannot be used concurrency. A conformance can be isolated to a global actor the same way as anything else in the language, e.g.,
33
-
```swift
34
-
@MainActor
35
-
structMyData: @MainActorP {
36
-
funcf() { }
37
-
}
38
-
```
32
+
* If all of the operations used to satisfy the protocol's requirements are on the same global actor (such as the main actor), the conformance itself can be isolated to that global actor. This allows the conformance to be used inside code running on that actor, but it cannot be used concurrently. A conformance can be isolated to a global actor the same way as anything else in the language, e.g.,
33
+
```swift
34
+
@MainActor
35
+
structMyData: @MainActorP {
36
+
funcf() { }
37
+
}
38
+
```
39
39
40
40
* If the conformance needs to be usable anywhere, then each of the operations used to satisfy its requirements must be marked `nonisolated`. This means that they will not have access to any actor-specific operations or state, because these operations can be called concurrently from anywhere. The result would look like this:
41
-
```swift
42
-
@MainActor
43
-
structMyData: P {
44
-
nonisolatedfuncf() { }
45
-
}
46
-
```
41
+
```swift
42
+
@MainActor
43
+
structMyData: P {
44
+
nonisolatedfuncf() { }
45
+
}
46
+
```
47
47
48
48
* If the protocol requirements themselves are meant to always be used from the correct isolation domain (for example, the main actor) but the protocol itself did not describe that requirement, the conformance can be marked with `@preconcurrency`. This approach moves isolation checking into a run-time assertion, which will produce a fatal error if an operation is called without already being on the right actor. A `@preconcurrency` conformance can be written as follows:
A protocol conformance can be isolated to a specific global actor, meaning that the conformance can only be used by code running on that actor. Isolated conformances are expressed by specifying the global actor on the conformance itself:
4
+
5
+
```swift
6
+
protocolP {
7
+
funcf()
8
+
}
9
+
10
+
@MainActor
11
+
classMyType: @MainActorP {
12
+
/*@MainActor*/funcf() {
13
+
// must be called on the main actor
14
+
}
15
+
}
16
+
```
17
+
18
+
Swift will produce diagnostics if the conformance is directly accessed in code that isn't guaranteed to execute in the same global actor. For example:
acceptP(myType) // error: main actor-isolated conformance of 'MyType' to 'P' cannot be used in nonisolated context
25
+
}
26
+
```
27
+
28
+
To address this issue, mark the code as having the same global actor as the conformance it is trying to use. In this case, mark `useIsolatedConformance` as `@MainActor` so that the code is guaranteed to execute on the main actor.
29
+
30
+
An isolated conformance cannot be used together with a `Sendable` requirement, because doing so would allow the conformance to cross isolation boundaries and be used from outside the global actor. For example:
31
+
32
+
```swift
33
+
funcacceptSendableP<T: P & Sendable>(_value: T) { }
acceptSendableP(myType) // error: main-actor-isolated conformance of 'MyType' to 'P' cannot satisfy conformance requirement for 'Sendable' type parameter 'T'
37
+
}
38
+
```
39
+
40
+
These errors can be addressed by either making the conformance itself `nonisolated` or making the generic function not require `Sendable`.
0 commit comments