Skip to content

[SwiftParser] Module-selected keyword references such as Module::as(x) are parsed as unexpected code #3387

Description

@thliu21

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions