Skip to content

Commit f8075da

Browse files
authored
Merge pull request #2786 from ahoppen/parse-const
Fix issue that causes `_const` to be parsed as a decl modifier
2 parents d992e0d + 6d4e79a commit f8075da

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

Sources/SwiftParser/Parameters.swift

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -263,17 +263,13 @@ extension Parser {
263263
mutating func parseParameterModifiers(isClosure: Bool) -> RawDeclModifierListSyntax {
264264
var elements = [RawDeclModifierSyntax]()
265265
var loopProgress = LoopProgressCondition()
266-
MODIFIER_LOOP: while self.hasProgressed(&loopProgress) {
267-
switch self.at(anyIn: ParameterModifier.self) {
268-
case (._const, let handle)?:
269-
elements.append(RawDeclModifierSyntax(name: self.eat(handle), detail: nil, arena: self.arena))
270-
case (.isolated, let handle)?
271-
where self.withLookahead({ !$0.startsParameterName(isClosure: isClosure, allowMisplacedSpecifierRecovery: false) }
272-
):
273-
elements.append(RawDeclModifierSyntax(name: self.eat(handle), detail: nil, arena: self.arena))
274-
default:
275-
break MODIFIER_LOOP
266+
while self.hasProgressed(&loopProgress) {
267+
guard let match = self.at(anyIn: ParameterModifier.self),
268+
!withLookahead({ $0.startsParameterName(isClosure: isClosure, allowMisplacedSpecifierRecovery: false) })
269+
else {
270+
break
276271
}
272+
elements.append(RawDeclModifierSyntax(name: self.eat(match.handle), detail: nil, arena: self.arena))
277273
}
278274
if elements.isEmpty {
279275
return self.emptyCollection(RawDeclModifierListSyntax.self)

Sources/SwiftParser/Patterns.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ extension Parser.Lookahead {
375375
&& !self.at(.keyword(.repeat))
376376
&& !self.at(.keyword(.__shared))
377377
&& !self.at(.keyword(.__owned))
378+
&& !self.at(.keyword(._const))
378379
&& !self.at(.keyword(.borrowing))
379380
&& !self.at(.keyword(.consuming))
380381
&& !(experimentalFeatures.contains(.sendingArgsAndResults) && self.at(.keyword(.sending)))

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3288,4 +3288,36 @@ final class DeclarationTests: ParserTestCase {
32883288
"""
32893289
)
32903290
}
3291+
3292+
func testConstAsArgumentLabel() {
3293+
assertParse(
3294+
"func const(_const: String) {}",
3295+
substructure: FunctionParameterSyntax(
3296+
firstName: .identifier("_const"),
3297+
colon: .colonToken(),
3298+
type: TypeSyntax(IdentifierTypeSyntax(name: .identifier("String")))
3299+
)
3300+
)
3301+
3302+
assertParse(
3303+
"func const(_const map: String) {}",
3304+
substructure: FunctionParameterSyntax(
3305+
firstName: .identifier("_const"),
3306+
secondName: .identifier("map"),
3307+
colon: .colonToken(),
3308+
type: TypeSyntax(IdentifierTypeSyntax(name: .identifier("String")))
3309+
)
3310+
)
3311+
3312+
assertParse(
3313+
"func const(_const x y: String) {}",
3314+
substructure: FunctionParameterSyntax(
3315+
modifiers: [DeclModifierSyntax(name: .keyword(._const))],
3316+
firstName: .identifier("x"),
3317+
secondName: .identifier("y"),
3318+
colon: .colonToken(),
3319+
type: TypeSyntax(IdentifierTypeSyntax(name: .identifier("String")))
3320+
)
3321+
)
3322+
}
32913323
}

0 commit comments

Comments
 (0)