Closure arguments parsed as attribute parameters
Closed this issue · 4 comments
Issue Kind
Parse of Valid Source Produced Invalid Syntax Tree
Source Code
f { @Sendable (e: Int) in }
Description
Parsing the code snippet, swift-parser-cli print-tree
produces the tree
SourceFileSyntax
├─statements: CodeBlockItemListSyntax
│ ╰─[0]: CodeBlockItemSyntax
│ ╰─item: FunctionCallExprSyntax
│ ├─calledExpression: DeclReferenceExprSyntax
│ │ ╰─baseName: identifier("f")
│ ├─arguments: LabeledExprListSyntax
│ ├─trailingClosure: ClosureExprSyntax
│ │ ├─leftBrace: leftBrace
│ │ ├─signature: ClosureSignatureSyntax
│ │ │ ├─attributes: AttributeListSyntax
│ │ │ │ ╰─[0]: AttributeSyntax
│ │ │ │ ├─atSign: atSign
│ │ │ │ ├─attributeName: IdentifierTypeSyntax
│ │ │ │ │ ╰─name: identifier("Sendable")
│ │ │ │ ├─leftParen: leftParen
│ │ │ │ ├─arguments: LabeledExprListSyntax
│ │ │ │ │ ╰─[0]: LabeledExprSyntax
│ │ │ │ │ ├─label: identifier("e")
│ │ │ │ │ ├─colon: colon
│ │ │ │ │ ╰─expression: DeclReferenceExprSyntax
│ │ │ │ │ ╰─baseName: identifier("Int")
│ │ │ │ ╰─rightParen: rightParen
│ │ │ ╰─inKeyword: keyword(SwiftSyntax.Keyword.in)
│ │ ├─statements: CodeBlockItemListSyntax
│ │ ╰─rightBrace: rightBrace
│ ╰─additionalTrailingClosures: MultipleTrailingClosureElementListSyntax
╰─endOfFileToken: endOfFile
which shows that (e: Int)
is interpreted as the parameter list of @Sendable
while it is actually meant to be the argument list for the closure.
Is this an ambiguity only the compiler can resolve with full type information available?
Tracked in Apple’s issue tracker as rdar://118608697
@ahoppen: I think @Sendable
is not the primary reason for the behavior. I see f { @A (e: Int) in }
is parsed in the same way, namely (e: Int)
as an argument list.
AFAIK @A (e: Int)
isn’t valid at the moment either.
_ = { @MainActor (e: Int) in
print(e) // error: /tmp/a.swift:2:9: error: cannot find 'e' in scope
}
You need to write this as
_ = { @MainActor
(e: Int) in
print(e)
}
I’m open to discussing whether the first variant should be allowed but that would be a separate issue since it’s not a discrepancy between the new and the old parser.
Okay. I see the difference. What behaves like the current parser is not a bug.