Skip to content

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

Merged
merged 1 commit into from
Feb 12, 2021

Conversation

rjmccall
Copy link
Contributor

Fixes SE-14120.

@rjmccall
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - f29074d

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - f29074d

@rjmccall
Copy link
Contributor Author

@swift-ci Please test source compatibility

@rjmccall
Copy link
Contributor Author

@swift-ci Please test

@rjmccall
Copy link
Contributor Author

Source compatibility failure seems to just be a previously-extant UPASS.

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - f29074d

@rjmccall
Copy link
Contributor Author

@swift-ci Please test Linux

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - f29074d

@rjmccall
Copy link
Contributor Author

@swift-ci Please clean smoke test linux

@rjmccall rjmccall merged commit 3918fb0 into swiftlang:main Feb 12, 2021
@rjmccall rjmccall deleted the diagnose-implicit-nested-self branch February 12, 2021 23:06
rjmccall added a commit that referenced this pull request Aug 19, 2021
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.
rjmccall added a commit to rjmccall/swift that referenced this pull request Sep 1, 2021
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.
WowbaggersLiquidLunch pushed a commit to WowbaggersLiquidLunch/swift that referenced this pull request Mar 31, 2022
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants