Runtime crash when calling functions with opaque return types stored as closures

The following code crashes at runtime:

protocol Worker { }

struct DummyWorker: Worker {
    init(_: Int) { }
}

let workerFactory: (Int) -> some Worker = DummyWorker.init

let worker = workerFactory(15)
print(worker)

It crashes when calling workerFactory with:

Thread 1: EXC_BAD_ACCESS (code=1, address=0xf)

The address from the crash message is influenced by the value of the parameter passed to workerFactory, for example workerFactory(4) will crash with address 0x4.

If I change the parameter type to [Int] (or any kind of array), the code no longer crashes, however as soon as I add another Int/Double/String/etc parameter it will again crash, but if I add a second array parameter it will not crash.

I think this is a compiler bug, but unsure where the bug is:

  • either the compiler should not allow declaring a type that consist of a function that returns an opaque value (if one tries to write a closure, the compiler won't allow it to use the some keyword)
  • or the bug is when the compiler wraps up the opaque value

Any thoughts, or suggestions of how to make this work with some? Using an existential (any) doesn't crash, but if possible I'd like to use some, as it carries better semantics.

2 Likes

Likely workaround: use a closure that calls the original function instead of just referring to it by name. Then the compiler’s less likely to forget whatever it’s missing.

But this is definitely a bug, so can you file it on GitHub?

Unfortunately that doesn't work, as the compiler doesn't allow some to be used when defining closures. I assume you were suggesting something like let workerFactory: (Int) -> some Worker = { DummyWorker($0) }

But this is definitely a bug, so can you file it on GitHub?

Sure, will do that.

Done, filed Runtime crash when calling functions with opaque return types, stored as closures · Issue #69057 · apple/swift · GitHub

Oh, if you can’t do that I’m not sure you can write a closure type () -> some Foo as the type of a value at all. :-/ So the resolution of the bug may be to emit an error rather than make it work. We’ll see from some present project members!

Yes, I though so, this is why I wasn't sure where the bug is: at the syntax checker level, or at the opaque types implementation level.

1 Like