@@ -919,7 +919,20 @@ object Parsers {
919
919
val next = in.lookahead.token
920
920
next == LBRACKET || next == LPAREN
921
921
922
- /* --------- OPERAND/OPERATOR STACK --------------------------------------- */
922
+ /** Is current ident a `*`, and is it followed by a `)` or `, )`? */
923
+ def followingIsVararg (): Boolean =
924
+ in.isIdent(nme.raw.STAR ) && {
925
+ val lookahead = in.LookaheadScanner ()
926
+ lookahead.nextToken()
927
+ lookahead.token == RPAREN
928
+ || lookahead.token == COMMA
929
+ && {
930
+ lookahead.nextToken()
931
+ lookahead.token == RPAREN
932
+ }
933
+ }
934
+
935
+ /* --------- OPERAND/OPERATOR STACK --------------------------------------- */
923
936
924
937
var opStack : List [OpInfo ] = Nil
925
938
@@ -956,8 +969,8 @@ object Parsers {
956
969
*/
957
970
def infixOps (
958
971
first : Tree , canStartOperand : Token => Boolean , operand : () => Tree ,
959
- isType : Boolean = false ,
960
- isOperator : => Boolean = true ,
972
+ isType : Boolean ,
973
+ isOperator : => Boolean ,
961
974
maybePostfix : Boolean = false ): Tree = {
962
975
val base = opStack
963
976
@@ -1522,15 +1535,9 @@ object Parsers {
1522
1535
*/
1523
1536
def infixType (): Tree = infixTypeRest(refinedType())
1524
1537
1525
- /** Is current ident a `*`, and is it followed by a `)` or `,`? */
1526
- def isPostfixStar : Boolean =
1527
- in.isIdent(nme.raw.STAR ) && {
1528
- val nxt = in.lookahead.token
1529
- nxt == RPAREN || nxt == COMMA
1530
- }
1531
-
1532
1538
def infixTypeRest (t : Tree ): Tree =
1533
- infixOps(t, canStartTypeTokens, refinedType, isType = true , isOperator = ! isPostfixStar)
1539
+ infixOps(t, canStartTypeTokens, refinedType, isType = true ,
1540
+ isOperator = ! followingIsVararg())
1534
1541
1535
1542
/** RefinedType ::= WithType {[nl] Refinement}
1536
1543
*/
@@ -2046,7 +2053,7 @@ object Parsers {
2046
2053
case t =>
2047
2054
syntaxError(em " `inline` must be followed by an `if` or a `match` " , start)
2048
2055
t
2049
- else expr1Rest(postfixExpr(), location)
2056
+ else expr1Rest(postfixExpr(location ), location)
2050
2057
end expr1
2051
2058
2052
2059
def expr1Rest (t : Tree , location : Location ): Tree = in.token match
@@ -2068,22 +2075,23 @@ object Parsers {
2068
2075
2069
2076
def ascription (t : Tree , location : Location ): Tree = atSpan(startOffset(t)) {
2070
2077
in.token match {
2071
- case USCORE =>
2078
+ case USCORE if in.lookahead.isIdent(nme.raw. STAR ) =>
2072
2079
val uscoreStart = in.skipToken()
2073
- if isIdent(nme.raw.STAR ) then
2074
- in.nextToken()
2075
- if ! (location.inArgs && in.token == RPAREN ) then
2076
- if opStack.nonEmpty then
2077
- report.errorOrMigrationWarning(
2078
- em """ `_*` can be used only for last argument of method application.
2079
- |It is no longer allowed in operands of infix operations. """ ,
2080
- in.sourcePos(uscoreStart))
2081
- else
2082
- syntaxError(SeqWildcardPatternPos (), uscoreStart)
2083
- Typed (t, atSpan(uscoreStart) { Ident (tpnme.WILDCARD_STAR ) })
2080
+ val isVarargSplice = location.inArgs && followingIsVararg()
2081
+ in.nextToken()
2082
+ if isVarargSplice then
2083
+ if sourceVersion.isAtLeast(`3.1`) then
2084
+ report.errorOrMigrationWarning(
2085
+ em " The syntax `x: _*` is no longer supported for vararg splices; use `x*` instead " ,
2086
+ in.sourcePos(uscoreStart))
2087
+ else if opStack.nonEmpty then
2088
+ report.errorOrMigrationWarning(
2089
+ em """ `_*` can be used only for last argument of method application.
2090
+ |It is no longer allowed in operands of infix operations. """ ,
2091
+ in.sourcePos(uscoreStart))
2084
2092
else
2085
- syntaxErrorOrIncomplete( IncorrectRepeatedParameterSyntax () )
2086
- t
2093
+ syntaxError( SeqWildcardPatternPos (), uscoreStart )
2094
+ Typed (t, atSpan(uscoreStart) { Ident (tpnme. WILDCARD_STAR ) })
2087
2095
case AT if ! location.inPattern =>
2088
2096
annotations().foldLeft(t)(Annotated )
2089
2097
case _ =>
@@ -2200,10 +2208,18 @@ object Parsers {
2200
2208
* | InfixExpr id [nl] InfixExpr
2201
2209
* | InfixExpr MatchClause
2202
2210
*/
2203
- def postfixExpr (): Tree = postfixExprRest(prefixExpr())
2211
+ def postfixExpr (location : Location = Location .ElseWhere ): Tree =
2212
+ val t = postfixExprRest(prefixExpr(), location)
2213
+ if location.inArgs && followingIsVararg() then
2214
+ Typed (t, atSpan(in.skipToken()) { Ident (tpnme.WILDCARD_STAR ) })
2215
+ else
2216
+ t
2204
2217
2205
- def postfixExprRest (t : Tree ): Tree =
2206
- infixOps(t, in.canStartExprTokens, prefixExpr, maybePostfix = true )
2218
+ def postfixExprRest (t : Tree , location : Location = Location .ElseWhere ): Tree =
2219
+ infixOps(t, in.canStartExprTokens, prefixExpr,
2220
+ isType = false ,
2221
+ isOperator = ! (location.inArgs && followingIsVararg()),
2222
+ maybePostfix = true )
2207
2223
2208
2224
/** PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr
2209
2225
*/
@@ -2331,7 +2347,7 @@ object Parsers {
2331
2347
if (in.token == RPAREN ) Nil else commaSeparated(exprInParens)
2332
2348
2333
2349
/** ParArgumentExprs ::= `(' [‘using’] [ExprsInParens] `)'
2334
- * | `(' [ExprsInParens `,'] PostfixExpr `:' `_' ` *' ')'
2350
+ * | `(' [ExprsInParens `,'] PostfixExpr `*' ')'
2335
2351
*/
2336
2352
def parArgumentExprs (): (List [Tree ], Boolean ) = inParens {
2337
2353
if in.token == RPAREN then
@@ -2614,7 +2630,7 @@ object Parsers {
2614
2630
*/
2615
2631
def pattern3 (): Tree =
2616
2632
val p = infixPattern()
2617
- if isPostfixStar then
2633
+ if followingIsVararg() then
2618
2634
atSpan(in.skipToken()) {
2619
2635
Typed (p, Ident (tpnme.WILDCARD_STAR ))
2620
2636
}
@@ -2646,7 +2662,8 @@ object Parsers {
2646
2662
*/
2647
2663
def infixPattern (): Tree =
2648
2664
infixOps(simplePattern(), in.canStartExprTokens, simplePattern,
2649
- isOperator = in.name != nme.raw.BAR && ! isPostfixStar)
2665
+ isType = false ,
2666
+ isOperator = in.name != nme.raw.BAR && ! followingIsVararg())
2650
2667
2651
2668
/** SimplePattern ::= PatVar
2652
2669
* | Literal
0 commit comments