> On May 13, 2016, at 8:18 AM, Matthew Johnson <[email protected]> wrote: > > > > Sent from my iPad > > On May 12, 2016, at 9:21 PM, Joe Groff <[email protected]> wrote: > >> >>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution >>> <[email protected]> wrote: >>> >>> The invariant StaticSelf identifier will always refer to A, unlike Self, >>> which is covarying and refers to >>> the type of the actual instance. Since multiple inheritance for >>> non-protocol types is disallowed, >>> this establishes this invariant type identifier with no possibility for >>> conflict. >>> >>> Consider the following example, under the current system: >>> >>> protocol StringCreatable >>> { >>> >>> static func createWithString(s: String) -> Self >>> >>> } >>> >>> >>> extension NSURL: StringCreatable >>> { >>> >>> // cannot conform because NSURL is non-final >>> >>> >>> // error: method 'createWithString' in non-final class 'NSURL' must return >>> `Self` to conform to protocol 'A' >>> >>> } >>> >>> Introducing a static, invariant version of Self permits the desired >>> conformance: >>> >>> protocol StringCreatable >>> { >>> >>> static func createWithString(s: String) -> StaticSelf >>> >>> } >>> >>> >>> extension NSURL: StringCreatable >>> { >>> >>> // can now conform conform because NSURL is fixed and matches the static >>> >>> >>> // type of the conforming construct. Subclasses need not re-implement >>> >>> >>> // NOTE: the return type can be declared as StaticSelf *or* as NSURL >>> >>> >>> // they are interchangeable >>> >>> >>> static func createWithString(s: String) -> StaticSelf >>> { >>> >>> // ... >>> >>> } >>> } >>> >>> >> >> As I've noted before, I don't think this makes sense to encode in the >> protocol. `Self` is already effectively invariant within a protocol. > > 'Self' is not invariant when used as a return type so I'm not sure what you > mean.
That's a property of a conformance. Class conformances are inherited, so they have to satisfy a protocol's requirements . Within the protocol definition, or in a protocol extension, `Self` is a generic parameter bound to a specific conforming type. When you conform a base class to a type, that means `Self == Base` and `Self == Derived` must be possible, but `Self` is never simultaneously `Base` and `Derived`. >> If a protocol doesn't have the foresight to use StaticSelf, then you still >> have the same problems retroactively conforming class hierarchies to the >> protocol. > > True, but in many use cases we are in control of the protocol. This has > always been the case when I have personally encountered this problem. That will likely change once resilient Swift frameworks start to exist. Changing `Self` to `StaticSelf` or back would also be a nonresilient change, so if frameworks get this wrong, they wouldn't be able to fix it without breaking ABI, which makes this even more problematic. -Joe _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
