-
Notifications
You must be signed in to change notification settings - Fork 440
Improve diagnostics for effect specifiers #1260
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
@swift-ci Please test |
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.
Nice 🤩
Sources/SwiftParser/Specifiers.swift
Outdated
} | ||
|
||
while let misplacedSpecifier = self.consume(ifAnyIn: EffectSpecifier.self) { | ||
if asyncKeyword == nil, S.correctAsyncTokenKinds.contains(misplacedSpecifier.tokenKind) || S.misspelledAsyncTokenKinds.contains(misplacedSpecifier.tokenKind) { |
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.
This is just AsyncEffectSpecifier
right? I think it'd be better to use subsets for all of this, it would be quite a few 😓 . But it doesn't seem great to eg. do the two array concatenations above. Plus if we want to remove the array ifAny
anyway...
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.
I knew this would come up. I updated it to use RawTokenKindSubset
unexpectedAfterThrows.append(RawSyntax(misplacedSpecifier)) | ||
} | ||
|
||
if unexpectedBeforeAsync.isEmpty && asyncKeyword == nil && unexpectedBeforeThrows.isEmpty && throwsKeyword == nil && unexpectedAfterThrows.isEmpty { |
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.
Checking all is fine, but since we always set async/throws we could just check those instead.
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.
I’d rather be conservative here to make sure we are not dropping any tokens.
while let (_, handle) = self.at(anyIn: EffectsSpecifier.self), loopProgress.evaluate(currentToken) { | ||
while let (_, handle) = self.at(anyIn: EffectSpecifier.self), loopProgress.evaluate(currentToken) { |
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.
We also handle unexpected up to the throws
from canRecoverTo
. We don't beyond that point though (see other comment).
let _: () 1️⃣throws | ||
} | ||
""", | ||
diagnostics: [ | ||
// TODO: Old parser expected error on line 3: consecutive statements on a line must be separated by ';' | ||
// TODO: Old parser expected error on line 3: expected expression | ||
DiagnosticSpec(message: "unexpected 'throws' keyword in function") |
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.
I assume this is parsed as let _: () // throws
ie. a variable with void type?
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.
Correct. Added a substructure test
@@ -760,7 +760,7 @@ final class DeclarationTests: XCTestCase { | |||
} | |||
""", | |||
diagnostics: [ | |||
DiagnosticSpec(message: "unexpected code 'bogus rethrows set' in variable") | |||
DiagnosticSpec(message: "unexpected code 'bogus' before effect specifiers") | |||
] | |||
) | |||
} |
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.
func foo() throws bogus {}
func foo() bogus -> Int {}
() bogus reasync -> Int
If I'm reading the code correctly I'm fairly sure they aren't handled well. It'd be good to add + fix these, but also happy to have that in a separate PR if you want though, since it's no worse than what's there at the moment.
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.
The first one is handled well. For the other two, I’ll look into them in a follow-up PR.
a733687
to
967cbc6
Compare
@swift-ci Please test |
Instead of modelling the effect specifiers as keywords in the declaration/signature, create dedicated nodes for them. This greatly simplifies how we can recover from incorrect effect specifiers.
967cbc6
to
798c660
Compare
Instead of modelling the effect specifiers as keywords in the declaration/signature, create dedicated nodes for them. This greatly simplifies how we can recover from incorrect effect specifiers.