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
@@ -107,8 +107,29 @@ This proposal adds dynamic actor isolation checking to:
107
107
}
108
108
```
109
109
110
+
- Call-sites of synchronous actor-isolated functions imported from Swift 6 libraries.
110
111
111
-
These are the most common circumstances when loosing actorisolation could be problematic and restricting runtime checking to them significantly limits negative performance impact of the new checks. The strategy of only emitting runtime checks when there’s potential for the function to be called from unchecked code is desirable, because it means the dynamic checks will be eliminated as more of the Swift ecosystem transitions to Swift 6.
112
+
When importing a module that was compiled with the Swift 6 language mode into code that is not, it's possible to call actor-isolated functions from outside the actorusing `@preconcurrency`. For example:
113
+
114
+
```swift
115
+
// ModuleA built with -swift-version 6
116
+
@MainActor public func onMain() { ... }
117
+
118
+
// ModuleB built with -swift-version 5 -strict-concurrency=minimal
119
+
importModuleA
120
+
121
+
@preconcurrency@MainActorfunccallOnMain() {
122
+
onMain()
123
+
}
124
+
125
+
funcnotIsolated() {
126
+
callOnMain()
127
+
}
128
+
```
129
+
130
+
In the above code, `onMain` from ModuleA can be called from outside the main actorvia a call to `notIsolated()`. To close this safety hole, a dynamic check is inserted at the call-site of `onMain()` when ModuleB is recompiled against ModuleA after ModuleA has migrated to the Swift 6 language mode.
131
+
132
+
These are the most common circumstances when losing actor isolation could be problematic and restricting runtime checking to them significantly limits negative performance impact of the new checks. The strategy of only emitting runtime checks when there’s potential for the function to be called from unchecked code is desirable, because it means the dynamic checks will be eliminated as more of the Swift ecosystem transitions to Swift 6.
112
133
113
134
114
135
## Detailed design
@@ -123,6 +144,10 @@ Runtime checking for actor isolation is not necessary for `async` functions, bec
123
144
124
145
A `@preconcurrency` protocol conformance is scoped to the implementation of the protocol requirements in the conforming type. A `@preconcurrency` conformance can be written at the primary declartaion or in an extension, and witness checker diagnostics about actor isolation will be suppressed. Like other `@preconcurrency` annotations, if no diagnotsics are suppressed, a warning will be emitted at the `@preconcurrency` annotation stating that the annotation has no effect and it should be removed.
125
146
147
+
### Disabling dynamic actor isolation checking
148
+
149
+
The dynamic actor isolation checks can be disabled using the flag `-disable-dynamic-actor-isolation`. Disabling dynamic actor isolation is discouraged, but it may be necessary if code that you don't control violates actor isolation in a way that causes the program to crash, such as by passing a non-`Sendable` function argument outside of a main actor context. `-disable-dynamic-actor-isolation` is similar to the `-enforce-exclusivity=unchecked` flag, which was a tool provided when staging in dynamic memory exclusivity enforcement under the Swift 5 lanugage mode.
150
+
126
151
## Source compatibility
127
152
128
153
Dynamic actor isolation checking can introduce new runtime assertions for existing programs. Therefore, dynamic actor isolation is only performed for synchronous functions that are witnesses to an explicitly annotated `@preconcurrency` protocol conformance, or that are compiled under the Swift 6 language mode.
@@ -147,6 +172,12 @@ The current approach in this proposal has a very desirable property of eliminate
147
172
148
173
If adoption of this feature exposes a bug in existing binaries because actor isolated code from outside the actor, a `@preconcurrency(unsafe)` annotation (or similar) could be provided to downgrade assertion failures to warnings. However, it's not clear whether allowing a known data race exhibited at runtime is the right approach to solving such a problem.
149
174
175
+
## Revision history
176
+
177
+
* Changes from the first review
178
+
* Insert dynamic checks at direct calls to synchronous actor-isolated functions imported from Swift 6 libraries.
179
+
* Add a flag to disable all dynamic actor isolation checking.
180
+
150
181
## Acknowledgments
151
182
152
183
Thank you to Doug Gregor for implementing the existing dynamic actor isolation checking gated behind `-enable-actor-data-race-checks`.
0 commit comments