I’m working on adding support for parsing async deinit in swift-syntax, but I’m a bit stuck with producing diagnostics.
These two probably are must haves:
// error: expected async specifier; did you mean 'async'? // fixit: replace 'reasync' with 'async' deinit await // error: deinit cannot throw // fixit: remove 'throws' deinit throws
Is one error sufficient here? Is second error useful in this case, or it does more harm than good?
// error: deinit cannot throw // fixit: remove 'throws' // error: 'async' must precede 'throws' // fixit: move 'async' in front of 'throws' deinit throws async
Should there be a diagnostics for
deinit? To my surprise currently this parses without any diagnostics:
async func foo() async deint
I’ve found existing code for parsing and producing diagnostics for effect specifiers for functions, accessors and types, and my first instinct was to generalise and reuse it for deinit case, but actually so far it's not working great.
DeinitEffectSpecifiers node, which contains only
ThrowsSpecifier, and then in extension conforming
RawEffectSpecifiersTrait added convenience initialiser that combines
MisspelledThrowsTokenKinds contains all 4 keywords, and
CorrectThrowsTokenKinds is uninhabited. With minimal changes I was able to reuse
parseEffectSpecifiers(), but diagnostics does not work well in this case.
In particular when trying to parse
deinit throws async, I end up with
asyncSpecifier being a synthesised token, while both real tokens end up in
I was hoping to reuse logic for producing
exchangeTokens() expect a single unexpected token, but I have two in this case.
I might be able to fix it by handling
throws and other keywords as
MisspelledAsyncSpecifiers, but that feels too hacky.
So, I'm considering the following options: