@@ -70,7 +70,9 @@ extension Parser {
70
70
// sequenced.
71
71
var lastElement : RawExprSyntax
72
72
73
- lastElement = self . parseSequenceExpressionElement ( flavor, forDirective: forDirective)
73
+ lastElement = self . parseSequenceExpressionElement ( flavor,
74
+ forDirective: forDirective,
75
+ inVarOrLet: inVarOrLet)
74
76
75
77
var loopCondition = LoopProgressCondition ( )
76
78
while loopCondition. evaluate ( currentToken) {
@@ -101,7 +103,9 @@ extension Parser {
101
103
lastElement = RawExprSyntax ( RawMissingExprSyntax ( arena: self . arena) )
102
104
break
103
105
} else {
104
- lastElement = self . parseSequenceExpressionElement ( flavor, forDirective: forDirective)
106
+ lastElement = self . parseSequenceExpressionElement ( flavor,
107
+ forDirective: forDirective,
108
+ inVarOrLet: inVarOrLet)
105
109
}
106
110
}
107
111
@@ -153,7 +157,7 @@ extension Parser {
153
157
case . infixQuestionMark:
154
158
// Save the '?'.
155
159
let question = self . eat ( . infixQuestionMark)
156
- let firstChoice = self . parseSequenceExpression ( flavor)
160
+ let firstChoice = self . parseSequenceExpression ( flavor, inVarOrLet : inVarOrLet )
157
161
// Make sure there's a matching ':' after the middle expr.
158
162
let ( unexpectedBeforeColon, colon) = self . expect ( . colon)
159
163
@@ -250,11 +254,13 @@ extension Parser {
250
254
@_spi ( RawSyntax)
251
255
public mutating func parseSequenceExpressionElement(
252
256
_ flavor: ExprFlavor ,
253
- forDirective: Bool = false
257
+ forDirective: Bool = false ,
258
+ inVarOrLet: Bool = false
254
259
) -> RawExprSyntax {
255
260
if self . currentToken. isContextualKeyword ( " await " ) {
256
261
let awaitTok = self . consumeAnyToken ( )
257
- let sub = self . parseSequenceExpressionElement ( flavor)
262
+ let sub = self . parseSequenceExpressionElement ( flavor,
263
+ inVarOrLet: inVarOrLet)
258
264
return RawExprSyntax ( RawAwaitExprSyntax (
259
265
awaitKeyword: awaitTok, expression: sub,
260
266
arena: self . arena) )
@@ -271,7 +277,9 @@ extension Parser {
271
277
}
272
278
273
279
guard self . at ( . tryKeyword) else {
274
- return self . parseUnaryExpression ( flavor, forDirective: forDirective)
280
+ return self . parseUnaryExpression ( flavor,
281
+ forDirective: forDirective,
282
+ inVarOrLet: inVarOrLet)
275
283
}
276
284
277
285
let tryKeyword = self . eat ( . tryKeyword)
@@ -282,7 +290,8 @@ extension Parser {
282
290
mark = nil
283
291
}
284
292
285
- let expression = self . parseSequenceExpressionElement ( flavor)
293
+ let expression = self . parseSequenceExpressionElement ( flavor,
294
+ inVarOrLet: inVarOrLet)
286
295
return RawExprSyntax ( RawTryExprSyntax (
287
296
tryKeyword: tryKeyword,
288
297
questionOrExclamationMark: mark,
@@ -302,31 +311,32 @@ extension Parser {
302
311
@_spi ( RawSyntax)
303
312
public mutating func parseUnaryExpression(
304
313
_ flavor: ExprFlavor ,
305
- forDirective: Bool = false
314
+ forDirective: Bool = false ,
315
+ inVarOrLet: Bool = false
306
316
) -> RawExprSyntax {
307
317
// First check to see if we have the start of a regex literal `/.../`.
308
318
// tryLexRegexLiteral(/*forUnappliedOperator*/ false)
309
319
switch self . currentToken. tokenKind {
310
320
case . prefixAmpersand:
311
321
let amp = self . eat ( . prefixAmpersand)
312
- let expr = self . parseUnaryExpression ( flavor)
322
+ let expr = self . parseUnaryExpression ( flavor, forDirective : forDirective , inVarOrLet : inVarOrLet )
313
323
return RawExprSyntax ( RawInOutExprSyntax (
314
324
ampersand: amp, expression: RawExprSyntax ( expr) ,
315
325
arena: self . arena) )
316
326
317
327
case . backslash:
318
- return RawExprSyntax ( self . parseKeyPathExpression ( forDirective: forDirective) )
328
+ return RawExprSyntax ( self . parseKeyPathExpression ( forDirective: forDirective, inVarOrLet : inVarOrLet ) )
319
329
320
330
case . prefixOperator:
321
331
let op = self . eat ( . prefixOperator)
322
- let postfix = self . parseUnaryExpression ( flavor, forDirective: forDirective)
332
+ let postfix = self . parseUnaryExpression ( flavor, forDirective: forDirective, inVarOrLet : inVarOrLet )
323
333
return RawExprSyntax ( RawPrefixOperatorExprSyntax (
324
334
operatorToken: op, postfixExpression: postfix,
325
335
arena: self . arena) )
326
336
327
337
default :
328
338
// If the next token is not an operator, just parse this as expr-postfix.
329
- return self . parsePostfixExpression ( flavor, forDirective: forDirective)
339
+ return self . parsePostfixExpression ( flavor, forDirective: forDirective, inVarOrLet : inVarOrLet )
330
340
}
331
341
}
332
342
@@ -347,9 +357,10 @@ extension Parser {
347
357
@_spi ( RawSyntax)
348
358
public mutating func parsePostfixExpression(
349
359
_ flavor: ExprFlavor ,
350
- forDirective: Bool
360
+ forDirective: Bool ,
361
+ inVarOrLet: Bool
351
362
) -> RawExprSyntax {
352
- let head = self . parsePrimaryExpression ( )
363
+ let head = self . parsePrimaryExpression ( inVarOrLet : inVarOrLet )
353
364
guard !head. is ( RawMissingExprSyntax . self) else {
354
365
return head
355
366
}
@@ -631,7 +642,7 @@ extension Parser {
631
642
/// key-path-postfixes → key-path-postfix key-path-postfixes?
632
643
/// key-path-postfix → '?' | '!' | 'self' | '[' function-call-argument-list ']'
633
644
@_spi ( RawSyntax)
634
- public mutating func parseKeyPathExpression( forDirective: Bool ) -> RawKeyPathExprSyntax {
645
+ public mutating func parseKeyPathExpression( forDirective: Bool , inVarOrLet : Bool ) -> RawKeyPathExprSyntax {
635
646
// Consume '\'.
636
647
let backslash = self . eat ( . backslash)
637
648
@@ -642,7 +653,7 @@ extension Parser {
642
653
// the token is a operator starts with '.', or the following token is '['.
643
654
let root : RawExprSyntax ?
644
655
if !self . currentToken. starts ( with: " . " ) {
645
- root = self . parsePostfixExpression ( . basic, forDirective: forDirective)
656
+ root = self . parsePostfixExpression ( . basic, forDirective: forDirective, inVarOrLet : inVarOrLet )
646
657
} else {
647
658
root = nil
648
659
}
@@ -689,7 +700,7 @@ extension Parser {
689
700
/// primary-expression → selector-expression
690
701
/// primary-expression → key-path-string-expression
691
702
@_spi ( RawSyntax)
692
- public mutating func parsePrimaryExpression( ) -> RawExprSyntax {
703
+ public mutating func parsePrimaryExpression( inVarOrLet : Bool ) -> RawExprSyntax {
693
704
switch self . currentToken. tokenKind {
694
705
case . integerLiteral:
695
706
let digits = self . eat ( . integerLiteral)
@@ -741,6 +752,16 @@ extension Parser {
741
752
let tok = self . eat ( . __dso_handle__Keyword)
742
753
return RawExprSyntax ( RawPoundDsohandleExprSyntax ( poundDsohandle: tok, arena: self . arena) )
743
754
case . identifier, . selfKeyword:
755
+ // If we have "case let x." or "case let x(", we parse x as a normal
756
+ // name, not a binding, because it is the start of an enum pattern or
757
+ // call pattern.
758
+ if inVarOrLet && !self . lookahead ( ) . isNextTokenCallPattern ( ) {
759
+ let identifier = self . parseAnyIdentifier ( )
760
+ let pattern = RawPatternSyntax ( RawIdentifierPatternSyntax (
761
+ identifier: identifier, arena: self . arena) )
762
+ return RawExprSyntax ( RawUnresolvedPatternExprSyntax ( pattern: pattern, arena: self . arena) )
763
+ }
764
+
744
765
// 'any' followed by another identifier is an existential type.
745
766
if self . currentToken. isContextualKeyword ( " any " ) ,
746
767
self . peek ( ) . tokenKind == . identifier,
@@ -2114,4 +2135,15 @@ extension Parser.Lookahead {
2114
2135
}
2115
2136
return true
2116
2137
}
2138
+
2139
+ fileprivate func isNextTokenCallPattern( ) -> Bool {
2140
+ switch self . peek ( ) . tokenKind {
2141
+ case . period,
2142
+ . prefixPeriod,
2143
+ . leftParen:
2144
+ return true
2145
+ default :
2146
+ return false
2147
+ }
2148
+ }
2117
2149
}
0 commit comments