I've run into another pattern that Swift 5.10 has flagged as unsafe. I'm really struggling to understand where the actor boundary here is. I've produced a somewhat reduced test case. Can anyone help me understand?
@MainActor
class A {
init(_ fn: () -> Void) {
}
}
class B {}
@MainActor
class C {
let b = B()
// Non-sendable type 'B' in asynchronous access to main actor-isolated property 'b' cannot cross actor boundary
lazy var a = A({ _ = b })
}
Hmm, I see no actor boundary and I also see no warning under -strict-concurrency=complete with the latest 5.10 development snapshot from February 8th. Can you please run swiftc --version and let me know which swiftlang tag or commit hash you're using?
Anyway, unless I am misunderstanding something, that closure is a non-Sendable closure formed on the @MainActor, so it's effectively @MainActor-isolated and accessing self.b should not be considered an asynchronous access. Something is causing the actor isolation checker to think that closure is nonisolated, in which case there would be an isolation boundary because B is not Sendable.
Right, lazy initializers should be run in the computed property for the lazy variable, which is in the isolation domain. That’s why I suspected the isolated default argument fix revolved the warning, because lazy variables have their initializers marked as “subsumed”.
Well, this is because I accidentally installed a development snapshot of main! I can reproduce the warning with the actual latest development snapshot of 5.10 from February 9th.
You can work around this by marking the closure parameter to A.init as @MainActor:
@MainActor
class A {
init(_ fn: @MainActor () -> Void) {
}
}
class B {}
@MainActor
class C {
let b = B()
lazy var a = A({ _ = b })
}
Funny enough, you can also work around this by changing that let to a var:
@MainActor
class A {
init(_ fn: () -> Void) {
}
}
class B {}
@MainActor
class C {
var b = B()
lazy var a = A({ _ = b })
}
I know that I can use the Swift evolution feature of swift.org to track the availability of proposals. Is there a way for me to know when a merged PR will become available?