@@ -18,6 +18,11 @@ extension TokenConsumer {
18
18
case ( . awaitTryMove, let handle) ? :
19
19
var backtrack = self . lookahead ( )
20
20
backtrack. eat ( handle)
21
+
22
+ // These can be parsed as expressions with try/await.
23
+ if backtrack. at ( anyIn: IfOrSwitch . self) != nil {
24
+ return true
25
+ }
21
26
if backtrack. atStartOfDeclaration ( ) || backtrack. atStartOfStatement ( ) {
22
27
// If after the 'try' we are at a declaration or statement, it can't be a valid expression.
23
28
// Decide how we want to consume the 'try':
@@ -191,6 +196,30 @@ extension Parser {
191
196
)
192
197
}
193
198
199
+ /// Parse an unresolved 'as' expression.
200
+ ///
201
+ /// type-casting-operator → 'as' type
202
+ /// type-casting-operator → 'as' '?' type
203
+ /// type-casting-operator → 'as' '!' type
204
+ ///
205
+ mutating func parseUnresolvedAsExpr(
206
+ handle: TokenConsumptionHandle
207
+ ) -> ( operator: RawExprSyntax , rhs: RawExprSyntax ) {
208
+ let asKeyword = self . eat ( handle)
209
+ let failable = self . consume ( ifAny: [ . postfixQuestionMark, . exclamationMark] )
210
+ let op = RawUnresolvedAsExprSyntax (
211
+ asTok: asKeyword,
212
+ questionOrExclamationMark: failable,
213
+ arena: self . arena
214
+ )
215
+
216
+ // Parse the right type expression operand as part of the 'as' production.
217
+ let type = self . parseType ( )
218
+ let rhs = RawTypeExprSyntax ( type: type, arena: self . arena)
219
+
220
+ return ( RawExprSyntax ( op) , RawExprSyntax ( rhs) )
221
+ }
222
+
194
223
/// Parse an expression sequence operators.
195
224
///
196
225
/// Returns `nil` if the current token is not at an operator.
@@ -323,19 +352,7 @@ extension Parser {
323
352
return ( RawExprSyntax ( op) , RawExprSyntax ( rhs) )
324
353
325
354
case ( . asKeyword, let handle) ? :
326
- let asKeyword = self . eat ( handle)
327
- let failable = self . consume ( ifAny: [ . postfixQuestionMark, . exclamationMark] )
328
- let op = RawUnresolvedAsExprSyntax (
329
- asTok: asKeyword,
330
- questionOrExclamationMark: failable,
331
- arena: self . arena
332
- )
333
-
334
- // Parse the right type expression operand as part of the 'as' production.
335
- let type = self . parseType ( )
336
- let rhs = RawTypeExprSyntax ( type: type, arena: self . arena)
337
-
338
- return ( RawExprSyntax ( op) , RawExprSyntax ( rhs) )
355
+ return parseUnresolvedAsExpr ( handle: handle)
339
356
340
357
case ( . async , _) ? :
341
358
if self . peek ( ) . tokenKind == . arrow || self . peek ( ) . tokenKind == . throwsKeyword {
@@ -487,6 +504,22 @@ extension Parser {
487
504
) -> RawExprSyntax {
488
505
// First check to see if we have the start of a regex literal `/.../`.
489
506
// tryLexRegexLiteral(/*forUnappliedOperator*/ false)
507
+
508
+ // Try parse an 'if' or 'switch' as an expression. Note we do this here in
509
+ // parseUnaryExpression as we don't allow postfix syntax to hang off such
510
+ // expressions to avoid ambiguities such as postfix '.member', which can
511
+ // currently be parsed as a static dot member for a result builder.
512
+ if self . at ( . keyword( . switch) ) {
513
+ return RawExprSyntax (
514
+ parseSwitchExpression ( switchHandle: . constant( . keyword( . switch) ) )
515
+ )
516
+ }
517
+ if self . at ( . keyword( . if) ) {
518
+ return RawExprSyntax (
519
+ parseIfExpression ( ifHandle: . constant( . keyword( . if) ) )
520
+ )
521
+ }
522
+
490
523
switch self . at ( anyIn: ExpressionPrefixOperator . self) {
491
524
case ( . prefixAmpersand, let handle) ? :
492
525
let amp = self . eat ( handle)
@@ -2461,6 +2494,11 @@ extension Parser.Lookahead {
2461
2494
return false
2462
2495
}
2463
2496
2497
+ // If this is the start of a switch body, this isn't a trailing closure.
2498
+ if self . peek ( ) . rawTokenKind == . keyword( . case) {
2499
+ return false ;
2500
+ }
2501
+
2464
2502
// If this is a normal expression (not an expr-basic) then trailing closures
2465
2503
// are allowed, so this is obviously one.
2466
2504
// TODO: We could handle try to disambiguate cases like:
0 commit comments