Hi,
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) {
print(value)
}
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-6.0.0.3.300 clang-1600.0.20.10)
Target: arm64-apple-macosx15.0