Open
Description
Description
Keypaths to global actor-isolated properties can be sent to other isolation domains and used there.
Reproduction
@MainActor
class MA {
var x: Int = 0
}
actor MyActor {
func hack(ma: MA, keyPath: sending ReferenceWritableKeyPath<MA, Int>) {
ma[keyPath: keyPath] += 1
}
}
@MainActor func test() async -> Int {
let a = MyActor()
let ma = MA()
Task {
await Task.yield()
await a.hack(ma: ma, keyPath: \MA.x) // ⚠️ passes!
}
await Task.yield()
return ma.x
}
var counts: [Int] = Array(repeating: 0, count: 2)
for _ in 0..<1000 {
counts[await test()] += 1
}
print(counts) // e.g. [997, 3]
Expected behavior
Keypath literals to global-actor isolated properties should be created in regions connected to that actor, to prevent them from being sent to other isolation domains.
Environment
Nightly toolchain - compiles, runs and produces output
Apple Swift version 6.2-dev (LLVM 21406e90d7382d7, Swift 90340a069a706c3)
Target: arm64-apple-macosx15.0
Build config: +assertions
Xcode-16.1 - compiles, runs but traps
swift-driver version: 1.115 Apple Swift version 6.0.2 (swiftlang-6.0.2.1.2 clang-1600.0.26.4)
Target: arm64-apple-macosx15.0
Additional information
No response