-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Diagnose the implicit use of self in nested closures #35898
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Diagnose the implicit use of self in nested closures #35898
Conversation
Fixes SE-14120.
@swift-ci Please test |
Build failed |
Build failed |
@swift-ci Please test source compatibility |
@swift-ci Please test |
Source compatibility failure seems to just be a previously-extant UPASS. |
Build failed |
@swift-ci Please test Linux |
Build failed |
@swift-ci Please clean smoke test linux |
Swift has diagnosed implicit uses of class-reference `self` in escaping closures for a long time as potentially leading to reference cycles. PR #35898 fixed a bug where we failed to diagnose this condition in nested closures. Unfortunately, treating this as an error has proven problematic because there's a lot of code doing it. Requiring that code to be thoroughly stamped out before we ship a compiler is just too much to ask. Stage the fix in by treating it as a warning in Swift versions prior to 6. As with the non-nested case, this warning can be suppressed by explicitly either capturing `self` or spelling out `self.` in the access. Fixes rdar://80847025.
We've always emitted an error if we saw an implicit use of a self parameter of class type from an escaping closure. In PR swiftlang#35898, I fixed this to also emit an error if the reference was to an explicit capture of self that wasn't made in the current closure. That was causing some source incompatibilities that we decided were too severe, so in PR swiftlang#38947 I weakened that to a warning when the diagnostic walk was within multiple levels of closures, because I have always thought of this as a fix to nested closures. However, this was the wrong condition in two ways. First, the diagnostic walk does not always start from the outermost function declaration; it can also start from a multi-statement closure. In that case, we'll still end up emitting an error when we see uses of explicit captures from the closure when we walk it, and so we still have a source incompatibility. That is rdar://82545600. Second, the old diagnostic did actually fire correctly in nested closures as long as the code was directly referring to the original self parameter and not any intervening captures. Therefore, swiftlang#38947 actually turned some things into warnings that had always been errors. The fix is to produce a warning exactly when the referenced declaration was an explicit capture.
We've always emitted an error if we saw an implicit use of a self parameter of class type from an escaping closure. In PR swiftlang#35898, I fixed this to also emit an error if the reference was to an explicit capture of self that wasn't made in the current closure. That was causing some source incompatibilities that we decided were too severe, so in PR swiftlang#38947 I weakened that to a warning when the diagnostic walk was within multiple levels of closures, because I have always thought of this as a fix to nested closures. However, this was the wrong condition in two ways. First, the diagnostic walk does not always start from the outermost function declaration; it can also start from a multi-statement closure. In that case, we'll still end up emitting an error when we see uses of explicit captures from the closure when we walk it, and so we still have a source incompatibility. That is rdar://82545600. Second, the old diagnostic did actually fire correctly in nested closures as long as the code was directly referring to the original self parameter and not any intervening captures. Therefore, swiftlang#38947 actually turned some things into warnings that had always been errors. The fix is to produce a warning exactly when the referenced declaration was an explicit capture.
Fixes SE-14120.