Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Sources/SwiftParser/Expressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,13 @@ extension Parser {
// Start of a closure in a context where it should be interpreted as
// being part of a statement.
|| (flavor == .stmtCondition && self.peek(isAt: .leftBrace))
// `unsafe.something` with no trivia
|| (self.peek(isAt: .period) && self.peek().leadingTriviaByteLength == 0
// Avoid treating as an "unsafe" expression when there is no trivia
// following the "unsafe" and the following token could either be a
// postfix expression or a subexpression:
// - Member access vs. leading .
// - Call vs. tuple expression.
// - Subscript vs. array or dictionary expression
|| (self.peek(isAt: .period, .leftParen, .leftSquare) && self.peek().leadingTriviaByteLength == 0
&& self.currentToken.trailingTriviaByteLength == 0)
{
break EXPR_PREFIX
Expand Down
40 changes: 40 additions & 0 deletions Tests/SwiftParserTest/ExpressionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2295,6 +2295,46 @@ final class StatementExpressionTests: ParserTestCase {
""",
substructure: DeclReferenceExprSyntax(baseName: .identifier("unsafe"))
)

assertParse(
"""
func f() {
unsafe()
}
""",
substructure: DeclReferenceExprSyntax(baseName: .identifier("unsafe"))
)

assertParse(
"""
func f() {
unsafe ()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, this is still source breaking because we parse it as a call to unsafe right now. But maybe it’s not too bad in practice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is. I'm trying to thread the needle here to the point where the source breakage in practice is near-zero, but we don't have to do semantic disambiguation for unsafe.

}
""",
substructure: UnsafeExprSyntax(
expression: TupleExprSyntax(elements: LabeledExprListSyntax())
)
)

assertParse(
"""
func f() {
unsafe[]
}
""",
substructure: DeclReferenceExprSyntax(baseName: .identifier("unsafe"))
)

assertParse(
"""
func f() {
unsafe []
}
""",
substructure: UnsafeExprSyntax(
expression: ArrayExprSyntax(expressions: [])
)
)
}

func testUnterminatedInterpolationAtEndOfMultilineStringLiteral() {
Expand Down