Skip to content

Commit dcca8ac

Browse files
authored
Merge pull request #3071 from rintaro/6.2-parse-rdar149556573
[6.2][SwiftParser] Parse operator function with value generics
2 parents 5ce35b8 + 64b745a commit dcca8ac

File tree

2 files changed

+12
-1
lines changed

2 files changed

+12
-1
lines changed

Sources/SwiftParser/Declarations.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -1215,8 +1215,11 @@ extension Parser {
12151215
let unexpectedAfterIdentifier: RawUnexpectedNodesSyntax?
12161216
let identifier: RawTokenSyntax
12171217
if self.at(anyIn: Operator.self) != nil || self.at(.exclamationMark, .prefixAmpersand) {
1218+
// If the name is an operator token that ends in '<' followed by an identifier or 'let',
1219+
// leave the '<' so it's parsed as a generic parameter clause. This allows things like
1220+
// 'func ==<T>(x:T, y:T) {}'.
12181221
var name = self.currentToken.tokenText
1219-
if !currentToken.isEditorPlaceholder && name.hasSuffix("<") && self.peek(isAt: .identifier) {
1222+
if !currentToken.isEditorPlaceholder && name.hasSuffix("<") && self.peek(isAt: .identifier, .keyword(.let)) {
12201223
name = SyntaxText(rebasing: name.dropLast())
12211224
}
12221225
unexpectedBeforeIdentifier = nil

Tests/SwiftParserTest/ValueGenericsTests.swift

+8
Original file line numberDiff line numberDiff line change
@@ -287,4 +287,12 @@ final class ValueGenericsTests: ParserTestCase {
287287
fixedSource: "func foo() -> (<#type#>-1) X"
288288
)
289289
}
290+
291+
func testOperatorFunc() {
292+
assertParse(
293+
"""
294+
func *<let X: Int, let Y: Int>(l: A<X>, r: A<Y>) -> Int { l.int * r.int }
295+
"""
296+
)
297+
}
290298
}

0 commit comments

Comments
 (0)