I started seeing an odd crash when compiling with Xcode 16.3/ Swift 6.1 and in Swift 6 language mode (still reproducible with Xcode 16.4 Beta 1).
I don't have a dedicated small reliable repro, but in my setup, the following view:
struct ContentView: View {
var body: some View {
Text("")
.task {
let service: API = Impl()
await service.foo() ← crash
}
}
}
Where the service is defined in a separate package (which may or may not have been compiled in Swift 6 mode):
@objc
protocol API {
func foo() async
}
class Impl: API {
func foo() async {}
}
Leads to a very frequent (~ 90% of the time) instant crash:
Thread 6 Queue : com.apple.root.user-initiated-qos.cooperative (concurrent)
#0 0x00000002495bcc48 in resumeTaskAfterContinuation ()
#1 0x00000002495bb8f8 in swift_continuation_resumeImpl ()
#2 0x0000000102310f4c in UnsafeContinuation.resume<>(returning:) ()
#3 0x000000010230fd6c in _resumeUnsafeContinuation<()>(_:_:) ()
#4 0x0000000103806090 in @objc completion handler block implementation for @escaping @callee_unowned @convention(block) () -> () with result type () ()
#5 0x0000000103e7e5a4 in @objc closure #1 in Impl.foo() ()
#6 0x0000000103e7e6ac in partial apply for @objc closure #1 in Impl.foo() ()
#7 0x00000001022f7448 in thunk for @escaping @callee_guaranteed @Sendable @async () -> () ()
#8 0x00000001022f75a4 in partial apply for thunk for @escaping @callee_guaranteed @Sendable @async () -> () ()
#9 0x00000001022f7680 in thunk for @escaping @isolated(any) @callee_guaranteed @async () -> () ()
#10 0x00000001022f77e4 in partial apply for thunk for @escaping @isolated(any) @callee_guaranteed @async () -> () ()
#11 0x00000001022f7acc in specialized thunk for @escaping @isolated(any) @callee_guaranteed @async () -> (@out A) ()
#12 0x00000001022f7c14 in partial apply for specialized thunk for @escaping @isolated(any) @callee_guaranteed @async () -> (@out A) ()
0x2495bcc1c <+96>: cmn x8, #0x1
0x2495bcc20 <+100>: b.ne 0x2495bcca0 ; <+228>
0x2495bcc24 <+104>: adrp x0, 33026
0x2495bcc28 <+108>: add x0, x0, #0xcc8 ; continuationChecking::ActiveContinuations
0x2495bcc2c <+112>: add x1, sp, #0x8
0x2495bcc30 <+116>: bl 0x2495bcce4 ; unsigned long std::__1::__hash_table<swift::ContinuationAsyncContext*, std::__1::hash<swift::ContinuationAsyncContext*>, std::__1::equal_to<swift::ContinuationAsyncContext*>, std::__1::allocator<swift::ContinuationAsyncContext*>>::__erase_unique<swift::ContinuationAsyncContext*>(swift::ContinuationAsyncContext* const&)
0x2495bcc34 <+120>: cbz x0, 0x2495bccbc ; <+256>
0x2495bcc38 <+124>: adrp x0, 33026
0x2495bcc3c <+128>: add x0, x0, #0xcc0 ; continuationChecking::ActiveContinuationsLock
0x2495bcc40 <+132>: bl 0x2495c32fc ; symbol stub for: os_unfair_lock_unlock
0x2495bcc44 <+136>: add x8, x20, #0x18
-> 0x2495bcc48 <+140>: ldapr x21, [x8] ← crash
It is definitely related to the @objc
annotation. The crash doesn't occur if I point to the implementation directly (or via some API
), or if I remove @objc
.
Does anyone have any thoughts/ suggestions?
Thanks!