-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[SE-0365] Allow implicit self for weak self
captures
#40702
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
Conversation
weak self
capturesweak self
captures
…ted as an invalid implicit self
…escaping () -> String = String()'
…t self from an outer closure
…ermit implicit self
@swift-ci please smoke test |
@swift-ci please build toolchain Windows platform |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! I have left two tiny comments but they can be addressed in a follow-up as well.
@@ -327,7 +332,7 @@ LookupResult TypeChecker::lookupMember(DeclContext *dc, | |||
dc->lookupQualified(type, name, subOptions, lookupResults); | |||
|
|||
for (auto found : lookupResults) | |||
builder.add(found, nullptr, type, /*isOuter=*/false); | |||
builder.add(found, nullptr, nullptr, type, /*isOuter=*/false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Please add /*baseDecl=*/
before new nullptr
.
} | ||
} | ||
|
||
if (conditionalStmt == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: if (!conditionalStmt)
@swift-ci please test |
@swift-ci please test Linux platform |
Thank you for the great contribution, @calda! |
Thank you for the quick reviews and thorough feedback @xedin! Really appreciate it. This was my first non-trivial compiler change so your input was really helpful. |
@@ -3,6 +3,48 @@ CHANGELOG | |||
|
|||
_**Note:** This is in reverse chronological order, so newer entries are added to the top._ | |||
|
|||
## Swift 6.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit: this should go under Swift 5.8, since part of the feature is there, and we aren't release "Swift 6.0" any time soon.
@calda The language workgroup discussed the problem and came to the conclusion that the compiler should:
Would you be interested in working on changes? |
Sure! I can work on these changes |
In what situations should this warning be emitted, and how would the warning be silenced? |
The same situations where the warning about "unused self" had to be suppressed in Swift 5 mode because it picks |
If we want a warning and this case: closure { [weak self] in
// warning: self is not unwrapped, add `guard let self else { return }`
method()
} and this case: closure { [weak self] in
// warning: guard condition is unused in Swift 5, but used in Swift 6
guard let self else { return }
method()
} then how do you write a It seems like we'd want a way to suppress the first warning without introducing a new warning. Thoughts? |
Probably the only way is to write explicit |
Should the fix-it suggest using explicit self instead of adding a guard statement? |
As far as I understand the guard/if let statements have to stay to produce |
Do we need a warning at all in this case, since the code is well-formed in Swift 6? closure { [weak self] in
guard let self else { return }
method()
} Allowing this without a warning may be better than having multiple warnings that needs to be suppressed in stages. |
This warning should be emitted only for language modes < 6 because in 6 and on it would pickup the right |
Sorry, I just want to make sure any new warning we add here has an actionable fix-it that silences it. For the warning in this example, what fixit would we use? closure { [weak self] in
// Warning: guard statement condition is unused in Swift 5 language mode
guard let self else { return }
method()
otherMethod()
} Would we emit the warning any time there's an implicit self reference that had its lookup behavior changed by Swift 6? e.g. would this case emit a warning? closure { [weak self] in
// warning?
guard let self else { return }
self.method()
otherMethod() // still implicit
} (the guard statement is not unused, but there's still an implicit self call that has its behavior changed in Swift 6) |
Yes, guard statement gets one warning and both |
We could also go in a direction where
|
Ok, this makes sense to me -- we emit a warning for each these implicit self calls that will have their behavior changed with a fix-it to use explicit self. This also silences the "unused guard statement" warning, since that is no longer unused after applying the fixits. Does that sound right? |
Take a look at my previous comment (i might have posted it while you where writing this message), you might find that a more interesting approach which reduces number of warnings produced. |
Thanks for the in-depth discussion! I think your suggestion of having a single warning with multiple notes would work really nicely here. |
Absolutely! Let's try to make it happen then, if it turns out too hard there is always a fallback to multiple warnings. |
Here you go: #61513 -- turned out to be pretty straightforward! |
This PR adds support for implicit self for
weak self
captures, as long asself
has been unwrapped.This implements SE-0365.
For example: