Type-erasing generics by using protocols to downcast generic parameter types

I don't understand why generics need to be type-erased using wrapper types. It seems like extra boilerplate to write, when the following should work (at least intuitively).

struct GenericContainer<X> {
  let x: X
}

protocol AnyContainer {
  var x: Any { get }
}

extension GenericContainer: AnyContainer {}
// error: type 'GenericContainer<X>' does not conform to protocol 'AnyContainer'
// note: candidate has non-matching type 'X'
// note: protocol requires property 'x' with type 'Any'; do you want to add a stub?

Why doesn't it work? "X" downcasts to "Any." E.g.

...

protocol AnyContainer {
  var any: Any { get }
}

extension GenericContainer: AnyContainer {
  var any: Any {
    x
  }
}

compiles with no errors.

Generics in Swift do not support covariance.

1 Like

It's not about generics:

protocol AnyContainer {
    var x: Any { get }
}
// error: type 'IntContainer' does not conform to protocol 'AnyContainer'
// note: candidate has non-matching type 'Int'
// note: protocol requires property 'x' with type 'Any'; do you want to add a stub?
struct IntContainer: AnyContainer {
    let x: Int
}

PS

Related thread–Protocol property requirements do not support subtyping?

2 Likes

I see, thanks @Lantua. Here are the relevant bugs.

https://bugs.swift.org/browse/SR-522
https://bugs.swift.org/browse/SR-1950

Terms of Service

Privacy Policy

Cookie Policy