[swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

Joe Groff jgroff at apple.com
Fri May 13 15:12:10 CDT 2016


> On May 13, 2016, at 9:06 AM, Matthew Johnson <matthew at anandabits.com> wrote:
> 
> 
>> On May 13, 2016, at 10:55 AM, Joe Groff <jgroff at apple.com> wrote:
>> 
>> 
>>> On May 13, 2016, at 8:18 AM, Matthew Johnson <matthew at anandabits.com> wrote:
>>> 
>>> When I write a class Base with non-final methods that return instances of Base I can choose whether to state the return type as Self (covariant) or Base (invariant, under this proposal StaticSelf would also be an alternative way to state this).  If I choose to specify Base as the return type derived classes *may* override the method but are not required to.  Further, if they *do* override the method they are allowed to choose whether their implementation returns Base or Derived.
>> 
>> `StaticSelf` requirements by themselves don't even save you from covariance. If Base conforms to a protocol (with Self == Base), Derived inherits that conformance and also conforms (with Self == Derived). If `StaticSelf` always refers to the conforming type, then it must also be bindable to Base and Derived, so a base class must still use a covariant-returning method to satisfy the `StaticSelf` requirement.
> 
> We are specifying that `StaticSelf` refers to the type that explicitly declares conformance.  If a class inherits conformance it refers to the base class which explicitly declared the conformance it is inheriting.

That makes `StaticSelf` tricky to use in generic code. This would be invalid:

protocol Makable {
	static func make(value: Int) -> StaticSelf
}

func makeWithZero<T: Fooable>(x: Int) -> T {
	return T.make(value: 0) // ERROR: T.StaticSelf may be a supertype of T so isn't convertible to T
}

`StaticSelf` in this model is effectively an associated type of the protocol, with a `Self: StaticSelf` constraint (if that were supported).

-Joe


More information about the swift-evolution mailing list