@@ -912,12 +912,13 @@ extension TokenConsumer {
912
912
mutating func atContextualKeywordPrefixedSyntax(
913
913
exprFlavor: Parser . ExprFlavor ,
914
914
acceptClosure: Bool = false ,
915
- preferPostfixExpr: Bool = true
915
+ preferPostfixExpr: Bool = true ,
916
+ allowNextLineOperand: Bool = false
916
917
) -> Bool {
917
918
let next = peek ( )
918
919
919
920
// The next token must be at the same line.
920
- if next. isAtStartOfLine {
921
+ if next. isAtStartOfLine && !allowNextLineOperand {
921
922
return false
922
923
}
923
924
@@ -990,26 +991,28 @@ extension TokenConsumer {
990
991
// - Call vs. tuple expression
991
992
// - Subscript vs. collection literal
992
993
//
993
- let hasSpace = ( next. leadingTriviaByteLength + currentToken. trailingTriviaByteLength) != 0
994
- if !hasSpace {
995
- // No space, the word is an decl-ref expression
994
+ if preferPostfixExpr {
996
995
return false
997
996
}
998
- return !preferPostfixExpr
997
+
998
+ // If there's no space between the tokens, consider it's an expression.
999
+ // Otherwise, it looks like a keyword followed by an expression.
1000
+ return ( next. leadingTriviaByteLength + currentToken. trailingTriviaByteLength) != 0
999
1001
1000
1002
case . leftBrace:
1001
1003
// E.g. <word> { ... }
1002
1004
// Trailing closure is also ambiguous:
1003
1005
//
1004
1006
// - Trailing closure vs. immediately-invoked closure
1005
1007
//
1006
- // Checking whitespace between the word cannot help this because people
1007
- // usually put a space before trailing closures. Even though that is source
1008
- // breaking, we prefer parsing it as a keyword if the syntax accepts
1009
- // immediately-invoked closure patterns. E.g. 'unsafe { ... }()'
1010
1008
if !acceptClosure {
1011
1009
return false
1012
1010
}
1011
+
1012
+ // Checking whitespace between the word cannot help this because people
1013
+ // usually put a space before trailing closures. Even though that is source
1014
+ // breaking, we prefer parsing it as a keyword if the syntax accepts
1015
+ // expressions starting with a closure. E.g. 'unsafe { ... }()'
1013
1016
return self . withLookahead {
1014
1017
$0. consumeAnyToken ( )
1015
1018
return $0. atValidTrailingClosure ( flavor: exprFlavor)
@@ -1070,7 +1073,7 @@ extension Parser.Lookahead {
1070
1073
case . yield? , . discard? :
1071
1074
return atContextualKeywordPrefixedSyntax ( exprFlavor: . basic, preferPostfixExpr: true )
1072
1075
case . then? :
1073
- return atContextualKeywordPrefixedSyntax ( exprFlavor: . basic, preferPostfixExpr: false )
1076
+ return atContextualKeywordPrefixedSyntax ( exprFlavor: . basic, preferPostfixExpr: false , allowNextLineOperand : !preferExpr )
1074
1077
1075
1078
case nil :
1076
1079
return false
0 commit comments