Strange compiler behaviour in implicitly opened existentials


I've been tinkering around generic functions and existential types and noticed strange compiler behaviour in this particular case. Suppose we have these declarations:

protocol Base {}

struct A: Base {}
struct B: Base {}

func foo(_ value: some Base) {

So, foo is generic function that accepts some value of some concrete type that is conforming to Base, so far so good.

Let's try to pass value of existential type any Base inside foo:

let thing: any Base = A()
foo(thing) // OK

This compiles and works fine, because of Implicitly Opened Existentials. However, let's try one more example:

let things: [any Base] = [A(), B()]
foo(things.first!) // Type 'any Base' cannot conform to 'Base'

Although thing in the first example and things.first! in the second example technically have the same type any Base, second example does not compile at all.

And here comes the plot twist:

let things: [any Base] = [A(), B()]
let thing = things.first!
foo(thing) // OK

For some reason, adding an intermediate variable to hold things.first! solves the problem. This code compiles fine.

My guess is that is a bug in Implicitly Opened Existentials feature. Should I file the bug report?

swift-driver version: 1.109.2 Apple Swift version 6.0 (swiftlang- clang-1600.0.20.10)
Target: arm64-apple-macosx15.0

Yeah, this looks like a bug.

1 Like

Thanks for quick response! Filed an issue.

1 Like