The keyword Self
inside a class is not a generic parameter, it is its own special thing primarily meant for Objective-C interoperability (it’s spelled instancetype
there). It is always the dynamic type of the instance and not the static type at the call site. Eg,
protocol P {}
class Base: P {
func f() { print(Self.self) }
}
extension P {
func g() { print(Self.self) }
}
class Derived: Base {}
(Derived() as Base).f()
(Derived() as Base).g()
Given this behavior returning a Foo<Self>
from a class method is unsound because we might get Foo<Base>
or Foo<Derived>
dynamically, but the two types are distinct and we don’t know which we would get.