+1. I have not encountered this issue myself but it looks like something that would cause a lot of head scratching if I had. It is also something that I am unlikely to remember immediately if I run into it in the future. The current behavior appears broken to me. It will be great to have it fixed.
> On Jun 23, 2016, at 2:53 PM, Slava Pestov via swift-evolution > <[email protected]> wrote: > > Consistent formal type for 'self' in class methods > > Proposal: SE-9999 > <https://github.com/slavapestov/swift-evolution/blob/self-formal-type-in-class/proposals/9999-self-formal-type-in-class.md> > Author: Slava Pestov <https://github.com/slavapestov> > Status: Awaiting review > Review manager: TBD > > > <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#introduction>Introduction > > This proposal makes the self value behave consistently whether or not it is > used from a method with a Self return type. > > Swift-evolution thread: Discussion thread topic for that proposal > <http://news.gmane.org/gmane.comp.lang.swift.evolution> > > <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#motivation>Motivation > > Right now, we exhibit inconsistent behavior when self is used as an argument > to a generic function, violating the principle of least surprise. > > Consider the following code: > > class Base { > @discardableResult > func methodWithDynamicSelf() -> Self { > doSomething(self) > return self > } > > func methodWithoutDynamicSelf() { > doSomething(self) > } > } > > class Derived : Base {} > > func doSomething<T>(_ t: T) { > print(T.self) > } > > Base().methodWithDynamicSelf() > Base().methodWithoutDynamicSelf() > > Derived().methodWithDynamicSelf() > Derived().methodWithoutDynamicSelf() > Currently, it prints the following output: > > Base > Base > Derived > Base > Note that there's no inconsistency when the method is called on the base > class. When called on the derived class however, we see that in a method with > a dynamic Self return type, the type of self is Derived, whereas in a method > with any other return type, the type of self is Base. > > > > <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#proposed-solution>Proposed > solution > > The proposal is to change the type of self to always be Self, which can be > thought of as a special generic type parameter bound to the dynamic type of > the instance. > > With this proposal, the above code will instead produce the following: > > Base > Base > Derived > Derived > Here, the type of self would always be Derived when called on an instance of > the derived class. > > Of course a more useful program could instead do something with the type > parameter T, such as constraining it to a protocol or a class with a required > initializer, and then using the type to construct a new instance of the class. > > This also dovetails nicely with SE-0068 > <https://github.com/slavapestov/swift-evolution/blob/self-formal-type-in-class/proposals/0068-universal-self.md>. > > Finally, it opens the door to generalizing dynamic Self, allowing it to > appear in covariant position within parameter types: > > class ArtClass { > func paint(withBrush: (Self) -> ()) { ... } > } > This would allow a class to conform to a protocol with a requirement written > like the following, something that is currently not possible at all: > > protocol OddProtocol { > func weaken<X, Y>((Self) -> (X) -> Y) -> (X) -> Y > } > > > <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#detailed-design>Detailed > design > > There's really not much more to say here. The code for typing self with a > dynamic Self is in place already, however enabling this change might expose > some new bugs we have not yet encountered, because currently, methods with > dynamic Self return type are relatively rare. > > > > <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#impact-on-existing-code>Impact > on existing code > > This will have a small impact on existing code that uses a pattern similar to > the above. > > > > <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#alternatives-considered>Alternatives > considered > > One alternative is to simply do nothing, but this makes the language less > consistent than it could be. > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
