Overridden methods can't have different actor isolation from nonisolated overridden declaration
Description
This is the same as https://github.com/swiftlang/swift/issues/75732, but a different example from init.
This makes working with XCTest almost impossible with Xcode 16.
Reproduction
@MainActor
final class MainActorType {
init() {}
}
@MainActor
final class TestsForMainActorType: XCTestCase {
// Main actor-isolated instance method 'setUp()' has different actor isolation from nonisolated overridden declaration
@MainActor
override func setUp() {
super.setUp()
// Removing `@MainActor` means this can't be called:
// Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context
type = .init()
// Can't call anything on `type` as preparation for every test, and same for `tearDown`.
}
private var type: MainActorType?
}
Expected behavior
This compiles
Environment
swift-driver version: 1.113 Apple Swift version 6.0 (swiftlang-6.0.0.7.6 clang-1600.0.24.1)
Target: arm64-apple-macosx14.0
cc @hborla
This is just one particular example with XCTest, but the bigger issue is that there are still lots of Apple frameworks that aren't ready for Swift 6, like Combine.
or GameplayKit
Basically anything that calls UIKit from any of the setUp/tearDown methods. This is a major impediment.
Having the same issue on Stevia unit tests.
One trick is to make setUp async throws like so:
@MainActor class LayoutTests: XCTestCase {
var v: UIView!
override func setUp() async throws {
// try await super.setUp() -> errors: Sending main actor-isolated value of type 'XCTestCase' with later accesses to nonisolated context risks causing data races
v = UIView()
}
But then calling super.setUp() errors out. @NachoSoto any news?
Nope. The reality is that XCTest (like Combine and many other Apple frameworks) isn't ready for Swift Concurrency.
Hey, I must have lived under a rock but I just realized new Swift Testing was I out so in my case it's just a matter of migrating XCTests to new Swift Testing \o/
But then calling super.setUp() errors out.
@s4cha If you mark the test class itself as Sendable then it works:
@MainActor final class LayoutTests: XCTestCase, Sendable {
...
}
@hborla I think this is solved by SE-0470?
Oh never mind, that's only for protocol conformances.
Yes that's right, SE-0470 is only for protocol conformances. I'm working on a proposal to apply similar techniques to subclasses to allow isolated overrides like this (using the basic approach outlined in the vision document). I think there are also similar challenges with metatypes.