In a non-final class, a designated initializer can be called as part of a super.init delegation from a derived class. The "self" value is going to be a partially initialized instance of the derived class in this case, with the derived class's stored properties already initialized but nothing else. It wouldn't make sense to replace "self" with a fully initialized instance while it is in this state.
I have a prototype implementation here: https://github.com/apple/swift/pull/19311
I am quite glad there is movement on this! It will definitely help swift-corelibs-foundation be not only more efficient but also work more in-line with the objc implementation for factory style initializers.
Per the designated initializer case it would be nice to allow this if and only if the type of self == the type that was allocated (e.g. a runtime check for the non-final case that Slava brought up). That change would allow SCLF to implement every case that should be a factory pattern.
Supporting that would require some fancier control-flow-sensitive analysis than we current do for definite initialization, since we'd have to ensure that a
self = assignment only occurred in a context where it was known that
Self == ConcreteClass. Maybe if we a type-refining cast feature like like what @grego proposes here we could confine self-assignments in a designated initializer to
if <Self == C> condition blocks.
Slightly off-topic, but would it make sense to add a similar feature to Swift like
instancetype from Objective-C. That type should bound the currently unconstrained
Self to something that you just mentioned
Self == C. This is really a missing feature for factory initializer in the context of designated initializers and it would also allow new and safe generic patterns to be expressed in Swift. What do you think @Joe_Groff?
instancetype. Factory initializers are interesting in that they do not always return
What's the update on this proposal? Anything blocking it?
I haven't had time to finish the implementation. There are still a few issues with the implementation in https://github.com/apple/swift/pull/19311/files that need to be fixed to get the tests passing.
This would be particularly helpful for classes that represent Core Data entities, as it would allow you to define initializers that use NSFetchRequests to retrieve information.