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