A colleague came up with an issue with the nil coalescing operator starting with Xcode 13.3 and 13.3.1 (Swift 5.6), which I was able to reproduce.
The following example always crashes, but worked fine till Xcode 13.2.1.
fileprivate typealias Closure = () -> Void
func crash1() {
let closure1: Closure? = nil
let closure2: Closure? = nil
let closure3: Closure? = nil
print("Closures: \(String(describing: closure1)), \(String(describing: closure2)), \(String(describing: closure3))")
let closure = closure1 ?? closure2 ?? closure3
print("\(#line): \(String(describing: closure))")
closure?() // <- EXC_BAD_ACCESS
assert(closure == nil)
}
func crash2() {
let closure1: Closure? = nil
let closure2: Closure? = nil
let closure3: Closure? = { }
print("Closures: \(String(describing: closure1)), \(String(describing: closure2)), \(String(describing: closure3))")
let closure = closure1 ?? closure2 ?? closure3
print("\(#line): \(String(describing: closure))")
closure?() // <- EXC_BAD_ACCESS
assert(closure != nil)
}
We reported it via https://github.com/apple/swift/issues/58323 and as FB10005210.
The following works fine and does not crash:
let closure = (closure1 ?? closure2) ?? closure3
Is anybody aware of this? As a workaround we need to limit nil coalescing to two items or use parentheses.
Update for Xcode 14.0 beta (14A5228q): Not crashing anymore, but closure is always nil, even if third coalescing returns a non-nil closure.