Description
The Swift compiler accepts module-selected calls to keyword-named declarations, but SwiftParser parses the calls as unexpected code.
Issue kind
Parse of valid source failed.
Reproducer
func `as`(_: Int) {}
func `is`(_: Int) {}
func use(_ x: Int) {
Module::as(x)
Module::is(x)
}
The source type-checks successfully when compiled with -module-name Module using Apple Swift 6.3.2.
On swift-syntax main at d7821debe6d2861206a438b6b85dc650117d97ff, each module-selected call is parsed as UnexpectedCodeDeclSyntax instead of FunctionCallExprSyntax. The argument x consequently never appears as a DeclReferenceExprSyntax.
Root cause
atStartOfExpression() consumes the module selector and recursively tests whether the following token can begin an unqualified expression. Lexer-classified keywords such as as and is fail that check.
This differs from parseDeclReferenceBase(), which already accepts any lexer-classified keyword after a module selector and remaps it to an identifier.
Expected result
Module::as and Module::is are parsed as DeclReferenceExprSyntax.
- Each complete call is parsed as
FunctionCallExprSyntax.
x is represented as the argument DeclReferenceExprSyntax.
- No parser diagnostic is emitted.
Actual result
- Each complete call becomes
UnexpectedCodeDeclSyntax.
- SwiftParser reports
unexpected code 'Module::as(x)' in source file and the equivalent diagnostic for is.
Validation
A local three-line lookahead fix plus regression coverage for Module::as(x) and Module::is(x) makes the focused test pass. All 19 ModuleSelectorTests continue to pass, and strict swift format lint passes for the changed parser and test files.
This parser behavior also causes the downstream SwiftLint unused_parameter false positive tracked in realm/SwiftLint#6816.
Description
The Swift compiler accepts module-selected calls to keyword-named declarations, but SwiftParser parses the calls as unexpected code.
Issue kind
Parse of valid source failed.
Reproducer
The source type-checks successfully when compiled with
-module-name Moduleusing Apple Swift 6.3.2.On swift-syntax
mainatd7821debe6d2861206a438b6b85dc650117d97ff, each module-selected call is parsed asUnexpectedCodeDeclSyntaxinstead ofFunctionCallExprSyntax. The argumentxconsequently never appears as aDeclReferenceExprSyntax.Root cause
atStartOfExpression()consumes the module selector and recursively tests whether the following token can begin an unqualified expression. Lexer-classified keywords such asasandisfail that check.This differs from
parseDeclReferenceBase(), which already accepts any lexer-classified keyword after a module selector and remaps it to an identifier.Expected result
Module::asandModule::isare parsed asDeclReferenceExprSyntax.FunctionCallExprSyntax.xis represented as the argumentDeclReferenceExprSyntax.Actual result
UnexpectedCodeDeclSyntax.unexpected code 'Module::as(x)' in source fileand the equivalent diagnostic foris.Validation
A local three-line lookahead fix plus regression coverage for
Module::as(x)andModule::is(x)makes the focused test pass. All 19ModuleSelectorTestscontinue to pass, and strictswift format lintpasses for the changed parser and test files.This parser behavior also causes the downstream SwiftLint
unused_parameterfalse positive tracked in realm/SwiftLint#6816.