I am encountering an error when trying to pass the result of an anonymous closure that produces a random boxed type conforming to the Shape protocol to a function expecting some Shape. Here is the code:
class Example {
func doSomething() {
let anyDrawable: any Shape = {
if Bool.random() {
return Circle()
} else {
return Rectangle()
}
}()
getShape(input: anyDrawable) // No error
getShape(input: {
if Bool.random() {
return Circle()
} else {
return Rectangle()
}
}() as any Shape) // Error: Type 'any Drawable' cannot conform to 'Drawable'
}
}
public protocol Shape {
associatedtype Content
func draw() -> String
}
public struct Circle: Shape {
public typealias Content = String
public func draw() -> String { "Drawing a Circle" }
public init() {}
}
public struct Rectangle: Shape {
public typealias Content = Int
public func draw() -> String { "Drawing a Rectangle" }
public init() {}
}
public func getShape(input: some Shape) {
_ = input.draw()
}
In the first case, where I store the result of the closure in a variable (anyDrawable) and pass it to the getShape(input:) method, everything works fine. However, when I try to directly pass the closure’s result (after casting it to any Shape) into the same method, I get the error:
Error: Type 'any Shape' cannot conform to 'Shape'
My understanding is that the getShape(input:) method uses the opaque type some Shape and implicitly unbox existential types and should be able to work with any type conforming to Shape. I am wondering if this is expected behavior, and if so, why the variable assignment works but passing the closure result directly does not.
Is there something I am missing about the interaction between any Shape, some Shape, implicit opening of boxed types by some Shape ?