Skip to content

Commit 11a5cb4

Browse files
committed
Reduce recovery precedence of arrow in function type to exprKeyword
Only allow recovery to the arrow with exprKeyword precedence so we only skip over misplaced identifiers and don't e.g. recover to an errow in a 'where' clause. rdar://106457182
1 parent ea09dab commit 11a5cb4

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,9 @@ extension Parser {
13761376

13771377
let output: RawReturnClauseSyntax?
13781378

1379-
if self.at(.arrow) || self.canRecoverTo(TokenSpec(.arrow, allowAtStartOfLine: false)) != nil {
1379+
/// Only allow recovery to the arrow with exprKeyword precedence so we only
1380+
/// skip over misplaced identifiers and don't e.g. recover to an errow in a 'where' clause.
1381+
if self.at(.arrow) || self.canRecoverTo(TokenSpec(.arrow, recoveryPrecedence: .exprKeyword)) != nil {
13801382
output = self.parseFunctionReturnClause(effectSpecifiers: &effectSpecifiers, allowNamedOpaqueResultType: true)
13811383
} else {
13821384
output = nil

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,17 @@ final class DeclarationTests: XCTestCase {
15311531
"""
15321532
)
15331533
}
1534+
1535+
func testWhereClauseWithFunctionType() {
1536+
// A function type in the where clause isn't semantically valid but its fine
1537+
// with the parser. Make sure we don't recover to the arrow to parse the
1538+
// function return type.
1539+
AssertParse(
1540+
"""
1541+
func badTypeConformance3<T>(_: T) where (T) -> () : EqualComparable { }
1542+
"""
1543+
)
1544+
}
15341545
}
15351546

15361547
extension Parser.DeclAttributes {

Tests/SwiftParserTest/translated/InvalidTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,7 @@ final class InvalidTests: XCTestCase {
205205
DiagnosticSpec(locationMarker: "2️⃣", message: "expected ')' in function type"),
206206
DiagnosticSpec(locationMarker: "3️⃣", message: "expected return type in function type"),
207207
DiagnosticSpec(locationMarker: "3️⃣", message: "expected ')' to end parameter clause"),
208-
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code '<T>()' in function signature"),
209-
DiagnosticSpec(locationMarker: "4️⃣", message: "unexpected code ')' in function"),
208+
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code '<T>() -> T)' in function"),
210209
]
211210
)
212211
}

0 commit comments

Comments
 (0)