Skip to content

[SR-2757][Sema] Mark VarDecl in capture lists #6490

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
Jan 6, 2017

Conversation

modocache
Copy link
Contributor

Fixes SR-2757.

Variables in capture lists are treated as 'let' constants, which can result in misleading, incorrect diagnostics. Mark them as such in order to produce better diagnostics.

Alternatively, these variables could be marked as implicit, but that results in other diagnostic problems: capture list variables that are never used produce warnings, but these warnings aren't normally emitted for implicit variables. Other assertions in the compiler also misfire when these variables are treated as implicit.

Another alternative would be to walk up the AST and determine whether the VarDecl, but there doesn't appear to be a way to do so.

Copy link
Contributor

@slavapestov slavapestov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good otherwise

@@ -22,6 +22,11 @@ var closure6 = $0 // expected-error {{anonymous closure argument not contained
var closure7 : Int =
{ 4 } // expected-error {{function produces expected type 'Int'; did you mean to call it with '()'?}} {{9-9=()}}

var capturedVariable = 1
var closure8 = { [closureVariable] in
capturedVariable += 1 // expected-error {{left side of mutating operator isn't mutable: 'capturedVariable' is an immutable capture list variable}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just "is an immutable capture"?

@modocache
Copy link
Contributor Author

Done! Thanks, @slavapestov!! Can't wait for CI to reopen, and for my first commit to Sema :)

@@ -3750,7 +3750,7 @@ void VarDecl::emitLetToVarNoteIfSimple(DeclContext *UseDC) const {
// since the user has to choose to apply this anyway.
if (auto *PBD = getParentPatternBinding()) {
// Don't touch generated or invalid code.
if (PBD->getLoc().isInvalid() || PBD->isImplicit())
if (PBD->getLoc().isInvalid() || PBD->isImplicit() || isCaptureList())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need PBD here, you can hoist this out.
Maybe, right after if (!isLet()) return; line:

// Don't touch capture list
if (isCaptureList()) return;

@modocache modocache force-pushed the ast branch 2 times, most recently from 9c8155b to cbe423d Compare December 26, 2016 23:53
@@ -3743,7 +3743,10 @@ void VarDecl::emitLetToVarNoteIfSimple(DeclContext *UseDC) const {

// Besides self, don't suggest mutability for explicit function parameters.
if (isa<ParamDecl>(this)) return;


// Don't suggest any fixes for caoture list elements.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) Spelling. caoture -> capture

bool isCaptureList() const { return DeclBits.CaptureList; }

/// \brief Mark this declaration as an element in a capture list.
void setCaptureList(bool captureList = true) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this only seems to be effectively read only, can this setter be removed and the bit set in the constructor?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea, thanks for the suggestion. Will do!

Fixes SR-2757.

Variables in capture lists are treated as 'let' constants, which can
result in misleading, incorrect diagnostics. Mark them as such in order
to produce better diagnostics, by adding an extra parameter to the
VarDecl initializer.

Alternatively, these variables could be marked as implicit, but that
results in other diagnostic problems: capture list variables that are
never used produce warnings, but these warnings aren't normally emitted for
implicit variables. Other assertions in the compiler also misfire when
these variables are treated as implicit.

Another alternative would be to walk up the AST and determine whether
the `VarDecl`, but there doesn't appear to be a way to do so.
@modocache
Copy link
Contributor Author

Thanks for the suggestion to move the IsCaptureList parameter to the initializer, @CodaFi! I had to change a lot of initializer callsites, I hope that's OK. I thought about making IsCaptureList = false by default, but it doesn't seem like any other Decl classes use default initializer parameters, so I held off.

@CodaFi
Copy link
Contributor

CodaFi commented Jan 4, 2017

@swift-ci please smoke test and merge.

@CodaFi
Copy link
Contributor

CodaFi commented Jan 4, 2017

Looks like LLDB is calling this constructor and will require an update. If you want to revert the change I requested to get this merged sooner, I think that would be fine. Otherwise, see the Linux test logs for the constructor that needs to be updated.

@modocache
Copy link
Contributor Author

No rush, I'd be happy to update the LLDB callsite as well. Expect an update before Monday.

@modocache
Copy link
Contributor Author

@swift-ci please smoke test Linux platform

modocache added a commit to modocache/swift-lldb that referenced this pull request Jan 6, 2017
swiftlang/swift#6490 modified the VarDecl to add a
boolean parameter to specify whether the variable was an element in a
closure capture list, in order to improve diagnostics in the Swift
compiler. Use this new parameter.
@modocache modocache changed the title [Sema] Mark VarDecl in capture lists [SR-2757][Sema] Mark VarDecl in capture lists Jan 6, 2017
@modocache
Copy link
Contributor Author

Please test with following pull request:
apple/swift-lldb#115

@swift-ci Please test

@CodaFi
Copy link
Contributor

CodaFi commented Jan 6, 2017

Wonderful ✨ . Thanks for the secondary patch.

⛵️

@CodaFi CodaFi merged commit 96f2a04 into swiftlang:master Jan 6, 2017
@modocache modocache deleted the ast branch January 6, 2017 04:37
@modocache
Copy link
Contributor Author

Thank you for the reviews and the suggestion to modify the initializer!

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.

5 participants