-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Description
Description
Compiler currently doesn't allow a function taking isolated parameter to be marked @concurrent or @MainActor, but it allows a closure capturing isolated parameter to do that. While the implementation appears to work well (see SIL below), it's quite misleading, especially when the closure is defined within an actor and captures self by calling methods or accessing properties.
Also, the behaviors of the two examples appears inconsistent. See table below.
| isolation specified by modifier | isolation specified by isolation parameter | where does fn1 runs? |
|
|---|---|---|---|
| example 1 | global executor | MainActor | MainActor |
| example 2 | MyGlobalActor | MainActor | MyGlobalActor |
Example 1) @concurrent + isolated parameter
SIL: https://swift.godbolt.org/z/qhKTWvWv3
func foo(_ isolation: isolated MainActor) async {
let c: @concurrent () async -> Void = {
fn1()
_ = isolation;
await fn2()
}
await bar(isolation, c)
}
func bar(_ isolation: isolated MainActor, _ fp: @concurrent () async -> Void) async {
await fp()
}
func fn1() {}
@MainActor
func fn2() {}
Below are what happen in closure c, based on its SIL:
- hop to MainActor
- call
fn1 - hop to MainActor
- call
fn2 - hop (back) to MainActor and return
Example 2) @MainActor + isolated parameter
SIL: https://swift.godbolt.org/z/c7MGfEzqn
@globalActor
actor MyGlobalActor {
static let shared = MyGlobalActor()
}
func foo(_ isolation: isolated MainActor) async {
let c: @MyGlobalActor () async -> Void = {
fn1()
_ = isolation;
await fn2()
}
await bar(isolation, c)
}
func bar(_ isolation: isolated MainActor, _ fp: @MyGlobalActor () async -> Void) async {
await fp()
}
func fn1() {}
@MainActor
func fn2() {}
Below are what happen in closure c, based on its SIL:
- hop to MyGlobalActor
- call
fn1 - hop to MainActor
- call
fn2 - hop back to MyGlobalActor and return
Reproduction
See above examples
Expected behavior
They shouldn't compile
Environment
Swift 6.2 and beyond (nightly, etc.)
Additional information
- I suspect this may also cause weird RBI issues.
- I also suspect Converting
nonisolated(nonsending)closure to@concurrentclosure may cause data race #87674 might be related to this issue, but I don't have more details yet.