Protocol requirements co/contra variance

In the following example:

class Base {}
class Derived: Base {}

class C {
    func foo(_ v: Base) {}
    func bar() -> Derived { Derived() }
}

I can call C's foo with instances of Derived:

let c = C()
c.foo(Derived())

and I can treat C's bar as returning instances of Base:

let v: Base = c.bar()

yet if I try to formally expressed these abilities in a form of protocol:

protocol P: AnyObject {
    func foo(_ v: Derived)
    func bar() -> Base
}

I can't conform C to this protocol:

extension C: P {} // πŸ›‘ Type 'C' does not conform to protocol 'P'

apparently because protocol conformance requires exact type matching (unlike the co/contra variance flexibility allowed in subclass methods overrides).

The question is: shouldn't swift allow it?

1 Like

Old (but relevant) thread from a couple years back:

1 Like

This reminded me it would be good to revive it again (seems like my PR got closed bc I had to recreate the fork) and hopefully get it merged.

2 Likes