While it's true that full implicit conversions suffer from those pitfalls, I don't think that needs to exclude a narrower solution specifically for subtyping. In Swift, we already allow implicit conversions from a variable to an existential whose protocol it conforms to, or from a class to a superclass, or even from T
to T?
. For example, we allow this:
protocol UnsafePointerProtocol {}
extension UnsafeMutablePointer: UnsafePointerProtocol {}
let pointer: UnsafePointerProtocol = UnsafeMutablePointer<Int>.allocate(capacity: 1)
and equally, if UnsafePointer
were a class
, we'd allow:
class UnsafeMutablePointer: UnsafePointer {}
let pointer: UnsafePointer = UnsafeMutablePointer<Int>.allocate(capacity: 1)
Let's say that we hypothetically allowed something like:
struct UnsafeMutablePointer<Pointee>: @subtypeConvertible UnsafePointer<Pointee> {
public func upcast() -> UnsafePointer<Pointee> {
return UnsafePointer(self)
}
}
I may be missing something, but I don't see how that's anything more harmful than the subtyping relationships that are already in the language. The issue I do see is that downcasts would not work as you'd expect; e.g.:
let pointer: UnsafePointer<Int> = UnsafeMutablePointer<Int>.allocate(capacity: 1)
let downcastPointer: UnsafeMutablePointer<Int>? = pointer as? UnsafeMutablePointer<Int> // nil
I don't know how to appropriately solve that for the UnsafePointer
case, since it's not safe to convert an immutable pointer to a mutable pointer in general – I think the only reasonable answer is for that cast to always fail. For other cases, though, if type-checker and runtime performance allows it, we could optionally allow something like the following:
enum GPUResource {
case texture(GPUTexture)
}
struct GPUTexture : @subtypeConvertible GPUResource {
// required
public func upcast() -> GPUResource {
return .texture(self)
}
// optional, only used for `as?` casts
public init?(downcastingFrom superType: GPUResource) -> GPUTexture? {
switch superType {
case .texture(let texture):
return texture
default:
return nil
}
}
}