Skip to content

Commit a996e41

Browse files
committed
SE-0458: Disambiguate postfix expressions vs. unsafe expressions more generally
Handle call-vs-tuple and subscript-vs-collection-expr disambiguation using the same "no trivia" rule that we used to disambiguite "unsafe.x" (which we treat as a member access) from "unsafe .x" (which we treat as an unsafe expression with a leading-dot member access). Fixes rdar://146459104.
1 parent 7b01db2 commit a996e41

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

Sources/SwiftParser/Expressions.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,13 @@ extension Parser {
455455
// Start of a closure in a context where it should be interpreted as
456456
// being part of a statement.
457457
|| (flavor == .stmtCondition && self.peek(isAt: .leftBrace))
458-
// `unsafe.something` with no trivia
459-
|| (self.peek(isAt: .period) && self.peek().leadingTriviaByteLength == 0
458+
// Avoid treating as an "unsafe" expression when there is no trivia
459+
// following the "unsafe" and the following token could either be a
460+
// postfix expression or a subexpression:
461+
// - Member access vs. leading .
462+
// - Call vs. tuple expression.
463+
// - Subscript vs. array or dictionary expression
464+
|| (self.peek(isAt: .period, .leftParen, .leftSquare) && self.peek().leadingTriviaByteLength == 0
460465
&& self.currentToken.trailingTriviaByteLength == 0)
461466
{
462467
break EXPR_PREFIX

Tests/SwiftParserTest/ExpressionTests.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,6 +2295,46 @@ final class StatementExpressionTests: ParserTestCase {
22952295
""",
22962296
substructure: DeclReferenceExprSyntax(baseName: .identifier("unsafe"))
22972297
)
2298+
2299+
assertParse(
2300+
"""
2301+
func f() {
2302+
unsafe()
2303+
}
2304+
""",
2305+
substructure: DeclReferenceExprSyntax(baseName: .identifier("unsafe"))
2306+
)
2307+
2308+
assertParse(
2309+
"""
2310+
func f() {
2311+
unsafe ()
2312+
}
2313+
""",
2314+
substructure: UnsafeExprSyntax(
2315+
expression: TupleExprSyntax(elements: LabeledExprListSyntax())
2316+
)
2317+
)
2318+
2319+
assertParse(
2320+
"""
2321+
func f() {
2322+
unsafe[]
2323+
}
2324+
""",
2325+
substructure: DeclReferenceExprSyntax(baseName: .identifier("unsafe"))
2326+
)
2327+
2328+
assertParse(
2329+
"""
2330+
func f() {
2331+
unsafe []
2332+
}
2333+
""",
2334+
substructure: UnsafeExprSyntax(
2335+
expression: ArrayExprSyntax(expressions: [])
2336+
)
2337+
)
22982338
}
22992339

23002340
func testUnterminatedInterpolationAtEndOfMultilineStringLiteral() {

0 commit comments

Comments
 (0)