I have this extension:
public extension Drawable {
@_disfavoredOverload func flatten() -> Image { .init(self) }
func flatten<T: PrimitiveDrawable>() -> T { .init(self) }
}
where
/// A standalone `Drawable` representation which can be flattened into.
public protocol PrimitiveDrawable: Drawable {
init(_ drawable: some Drawable)
}
fileprivate struct PanicDrawable: PrimitiveDrawable {
public init(_ drawable: some Drawable) { fatalError() }
public var width: Int { fatalError() }
public var height: Int { fatalError() }
public subscript(x: Int, y: Int) -> Color { fatalError() }
}
fileprivate func test() {
let x = Rectangle(width: 10, height: 10).flatten<PanicDrawable>()
}
What I find odd is that while flatten
can infer the result type if I add an explicit annotation to x
, it completely ignores (yet allows specifying) the generics passed to flatten
In fact, this completely wrong expression works:
let x: Image = Rectangle(width: 10, height: 10).flatten<PanicDrawable>()
And it's result is an Image
, yet the LSP shows the method signature to be the generic one, which according to the parameter should return a completely different type.
The intention was to have a default overload of flatten
in case no type can be inferred, as Image
is the most primitive Drawable
and makes sense as the default — being a simple 2d color array.
edit:
Invalid syntax compiling aside, it is seemingly possible to achieve what I was after by adding a third overload:
func flatten<T>(into type: T.Type) -> T where T: PrimitiveDrawable { .init(self) }