I've been working on landing the implementation of SE-0365. I previously thought implicit self calls were never allowed for weak self
captures, but have found that this is actually allowed in non-escaping closures (even when self
is optional):
For example, this compiles in Swift 5.7:
class Object {
func getSelf() -> Object {
self
}
func test() {
doVoidStuff { [weak self] in
let getSelf: () -> Object = getSelf // refers to self.getSelf
let nonoptionalSelf: Object = getSelf()
let optionalSelf: Object? = self
}
}
}
func doVoidStuff(_ closure: () -> Void) { closure() }
This is surprising to me, considering self
is optional here so, at a minimum, a reference to a function or property on self
should have an optional type, right?
I haven't been able to construct an example where this is unsafe, since I think self
is practically speaking always guaranteed to exist for the lifetime of a non-escaping closure (right?). However it seems incorrect to me based on my understanding of the user-facing model of how weak self
works.
Does anyone know why this behavior exists? Is this intentional? There aren't any tests for this in the compiler's main test suite (and just a single example in the source compatibility suite) which makes me think this could potentially be a bug.
Even if this is a bug, I don't think we can remove support for it in Swift 5.8 (right?). Would it make sense to remove support for this in Swift 6?