Xcode 16.3: UnsafeContinuation.resume EXC_BAD_ACCESS crash

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!

Is this perhaps the same as @objc func foo() async? ? It had been labeled as „works as intended“ (aka we don’t care).

The corresponding [SR-15291] Concurrency: Crash when invoking async @objc function · Issue #57613 · swiftlang/swift · GitHub is also still open :man_shrugging:t3: