Skip to content

Commit 889ac42

Browse files
committed
Fix parsing generic argument lists of variadic types in expression context
We need to allow empty argument lists, and accept '...' in canParseType().
1 parent cdbdcba commit 889ac42

File tree

2 files changed

+36
-18
lines changed

2 files changed

+36
-18
lines changed

Sources/SwiftParser/Types.swift

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -618,22 +618,26 @@ extension Parser.Lookahead {
618618
break
619619
}
620620

621-
guard self.isAtFunctionTypeArrow() else {
622-
return true
623-
}
621+
if self.isAtFunctionTypeArrow() {
622+
// Handle type-function if we have an '->' with optional
623+
// 'async' and/or 'throws'.
624+
var loopProgress = LoopProgressCondition()
625+
while let (_, handle) = self.at(anyIn: EffectsSpecifier.self), loopProgress.evaluate(currentToken) {
626+
self.eat(handle)
627+
}
624628

625-
// Handle type-function if we have an '->' with optional
626-
// 'async' and/or 'throws'.
627-
var loopProgress = LoopProgressCondition()
628-
while let (_, handle) = self.at(anyIn: EffectsSpecifier.self), loopProgress.evaluate(currentToken) {
629-
self.eat(handle)
629+
guard self.consume(if: .arrow) != nil else {
630+
return false
631+
}
632+
633+
return self.canParseType()
630634
}
631635

632-
guard self.consume(if: .arrow) != nil else {
633-
return false
636+
if self.currentToken.isEllipsis {
637+
self.consumeAnyToken()
634638
}
635639

636-
return self.canParseType()
640+
return true
637641
}
638642

639643
mutating func canParseTupleBodyType() -> Bool {
@@ -822,14 +826,16 @@ extension Parser.Lookahead {
822826
}
823827

824828
self.consumePrefix("<", as: .leftAngle)
825-
var loopProgress = LoopProgressCondition()
826-
repeat {
827-
guard self.canParseType() else {
828-
return false
829-
}
830-
// Parse the comma, if the list continues.
831-
} while self.consume(if: .comma) != nil && loopProgress.evaluate(currentToken)
832829

830+
if !self.currentToken.starts(with: ">") {
831+
var loopProgress = LoopProgressCondition()
832+
repeat {
833+
guard self.canParseType() else {
834+
return false
835+
}
836+
// Parse the comma, if the list continues.
837+
} while self.consume(if: .comma) != nil && loopProgress.evaluate(currentToken)
838+
}
833839

834840
guard self.currentToken.starts(with: ">") else {
835841
return false

Tests/SwiftParserTest/TypeTests.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,18 @@ final class TypeParameterPackTests: XCTestCase {
374374
func f1<T ...>(_ x: T ...) -> (T ...) {}
375375
""")
376376
}
377+
func testVariadicTypes() {
378+
AssertParse(
379+
"""
380+
let _: G< > = G()
381+
let _: G<T... > = G()
382+
let _: G<Int, T... > = G()
383+
let _ = G< >.self
384+
let _ = G<T... >.self
385+
let _ = G<Int, T... >.self
386+
""")
387+
388+
}
377389

378390
func testMissingCommaInType() throws {
379391
AssertParse(

0 commit comments

Comments
 (0)