Skip to content

Commit 236e14a

Browse files
committed
Harden Closure Capture Parsing
Fix a regression where we didn't recognize unowned(safe) in closure captures. Fixes #722 rdar://99657725
1 parent 0ab0498 commit 236e14a

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

Sources/SwiftParser/Expressions.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,15 +1694,17 @@ extension Parser {
16941694
// Parse identifier (',' identifier)*
16951695
var keepGoing: RawTokenSyntax? = nil
16961696
repeat {
1697+
let unexpected: RawUnexpectedNodesSyntax?
16971698
let name: RawTokenSyntax
16981699
if self.currentToken.isIdentifier {
1700+
unexpected = nil
16991701
name = self.consumeIdentifier()
17001702
} else {
1701-
name = self.eat(.wildcardKeyword)
1703+
(unexpected, name) = self.expect(.wildcardKeyword)
17021704
}
17031705
keepGoing = consume(if: .comma)
17041706
params.append(RawClosureParamSyntax(
1705-
name: name, trailingComma: keepGoing, arena: self.arena))
1707+
unexpected, name: name, trailingComma: keepGoing, arena: self.arena))
17061708
} while keepGoing != nil && loopProgress.evaluate(currentToken)
17071709
}
17081710

@@ -1751,7 +1753,11 @@ extension Parser {
17511753
specifiers.append(self.consumeIdentifier())
17521754
if let lparen = self.consume(if: .leftParen) {
17531755
specifiers.append(lparen)
1754-
specifiers.append(self.expectWithoutLookahead(.identifier, "unsafe"))
1756+
if self.currentToken.tokenText == "safe" {
1757+
specifiers.append(self.expectWithoutLookahead(.identifier, "safe"))
1758+
} else {
1759+
specifiers.append(self.expectWithoutLookahead(.identifier, "unsafe"))
1760+
}
17551761
specifiers.append(self.expectWithoutLookahead(.rightParen))
17561762
}
17571763
} else if (self.currentToken.isIdentifier || self.at(.selfKeyword)) {

Tests/SwiftParserTest/Expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ final class ExpressionTests: XCTestCase {
443443
)
444444
}
445445

446-
func testClouserExpression() {
446+
func testClosureExpression() {
447447
AssertParse(
448448
"""
449449
let :(#^DIAG_1^#..)->

Tests/SwiftParserTest/Types.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,9 @@ final class TypeTests: XCTestCase {
3939
throws -> Void in }
4040
""",
4141
{ $0.parseClosureExpression() })
42+
43+
AssertParse("""
44+
{ [weak a, unowned(safe) self, b = 3] (a: Int, b: Int, _: Int) -> Int in }
45+
""")
4246
}
4347
}

0 commit comments

Comments
 (0)