There we are: a crasher that involves sending
. No compiler warning, no compiler error, but a runtime crash:
/// This class takes place of CurrentValueSubject.
/// It is not sendable, and in our particular case we
/// want to make sure its `send` method is called on the
/// main actor.
class MySubject {
func send() {
MainActor.assumeIsolated {
print("Good: on main thread")
}
}
}
@available(*, unavailable)
extension MySubject: Sendable { }
/// A class that builds a MainActor-isolated subject, and calls its `send`
/// method from a non-isolated context.
final class Context: Sendable {
@MainActor func makeSubject() -> sending MySubject {
MySubject()
}
func send() async {
await makeSubject().send()
}
}
@main struct App {
static func main() async {
let context = Context()
// Will it crash? Yes it crashes.
await context.send()
}
}