Description
Description
The new functionality of the cast operators to dynamically fail if not called on the main actor is currently unimplemented (#82539), but even if this is implemented, there's still two problems casting isolated conformances.
Reproduction
The first problem is where a type has an isolated conformance to a protocol which inherits from Sendable:
import Dispatch
protocol P: Sendable {
func f()
}
@MainActor
struct S: @MainActor P {
func f() {
MainActor.preconditionIsolated()
}
}
@MainActor
func example(_ s: any Sendable) {
let p = s as! any P // on the main actor, so the cast is allowed dynamically
DispatchQueue.global().async {
p.f() // oops, sent it anyway
}
}
example(S())
dispatchMain()
I believe isolated conformances should be disallowed in this case.
The second problem involves sending
the result of a cast:
import Dispatch
protocol P {
func f()
}
@MainActor
struct S: @MainActor P {
func f() {
MainActor.preconditionIsolated()
}
}
@MainActor
func example(_ s: sending Any) {
let p = s as! any P // cast is dynamically OK
Task.detached {
p.f() // oops, sending
}
}
example(S())
dispatchMain()
I don't see how to resolve this without having the cast operators join the result to the calling function's region, which is definitely source-breaking in some circumstances.
Expected behavior
SE-0470 shouldn't leave soundness holes
Environment
swift-driver version: 1.127.5.3 Apple Swift version 6.2 (swiftlang-6.2.0.10.950 clang-1700.3.10.950)
Target: arm64-apple-macosx15.0
Additional information
No response