Great to hear some feedback so quickly, especially about something so mundane.

I suspect the real reason it doesn’t work this way now is that ‘Self’ is not 
fully plumbed through. In particular, if a closure captures the ‘Self’ type, 
IRGen does not properly codegen it, causing compile-time or run-time crashes:

class MyClass {
        func foo(x: Int) -> Self {

                // Crash!
                _ = { print(self); print(x) }

                return self
        }

        func bar(x: Int) -> MyClass {

                // OK!
                _ = { print(self); print(x) }

                return self
        }
}

Assertion failed: (LocalSelf && "no local self metadata"), function 
getLocalSelfMetadata, file /Users/slava/new/swift/lib/IRGen/GenType.cpp, line 
1805.
0  swift                    0x0000000114d5276e 
llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 46
1  swift                    0x0000000114d52c99 
PrintStackTraceSignalHandler(void*) + 25
2  swift                    0x0000000114d4efc9 llvm::sys::RunSignalHandlers() + 
425
3  swift                    0x0000000114d53312 SignalHandler(int) + 354
4  libsystem_platform.dylib 0x00007fffc438a01a _sigtramp + 26
5  libsystem_platform.dylib 0x00000000507ca710 _sigtramp + 2353268496
6  swift                    0x0000000114d52cbb raise + 27
7  swift                    0x0000000114d52d62 abort + 18
8  swift                    0x0000000114d52d4e __assert_rtn + 126
9  swift                    0x000000010f6e8524 
swift::irgen::IRGenFunction::getLocalSelfMetadata() + 100

This comes up most frequently with the ‘weak self / strong self’ dance.

I’m going to fix this bug really soon, and it seems logical to deal with the 
language wart as well. We need the IRGen fix for SE-0086 as well in any case.

Slava

> On Jun 23, 2016, at 1:08 PM, Matthew Johnson <[email protected]> wrote:
> 
> +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] <mailto:[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] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to