@@ -919,7 +919,20 @@ object Parsers {
919919 val next = in.lookahead.token
920920 next == LBRACKET || next == LPAREN
921921
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 --------------------------------------- */
923936
924937 var opStack : List [OpInfo ] = Nil
925938
@@ -956,8 +969,8 @@ object Parsers {
956969 */
957970 def infixOps (
958971 first : Tree , canStartOperand : Token => Boolean , operand : () => Tree ,
959- isType : Boolean = false ,
960- isOperator : => Boolean = true ,
972+ isType : Boolean ,
973+ isOperator : => Boolean ,
961974 maybePostfix : Boolean = false ): Tree = {
962975 val base = opStack
963976
@@ -1522,15 +1535,9 @@ object Parsers {
15221535 */
15231536 def infixType (): Tree = infixTypeRest(refinedType())
15241537
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-
15321538 def infixTypeRest (t : Tree ): Tree =
1533- infixOps(t, canStartTypeTokens, refinedType, isType = true , isOperator = ! isPostfixStar)
1539+ infixOps(t, canStartTypeTokens, refinedType, isType = true ,
1540+ isOperator = ! followingIsVararg())
15341541
15351542 /** RefinedType ::= WithType {[nl] Refinement}
15361543 */
@@ -2046,7 +2053,7 @@ object Parsers {
20462053 case t =>
20472054 syntaxError(em " `inline` must be followed by an `if` or a `match` " , start)
20482055 t
2049- else expr1Rest(postfixExpr(), location)
2056+ else expr1Rest(postfixExpr(location ), location)
20502057 end expr1
20512058
20522059 def expr1Rest (t : Tree , location : Location ): Tree = in.token match
@@ -2068,22 +2075,23 @@ object Parsers {
20682075
20692076 def ascription (t : Tree , location : Location ): Tree = atSpan(startOffset(t)) {
20702077 in.token match {
2071- case USCORE =>
2078+ case USCORE if in.lookahead.isIdent(nme.raw. STAR ) =>
20722079 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))
20842092 else
2085- syntaxErrorOrIncomplete( IncorrectRepeatedParameterSyntax () )
2086- t
2093+ syntaxError( SeqWildcardPatternPos (), uscoreStart )
2094+ Typed (t, atSpan(uscoreStart) { Ident (tpnme. WILDCARD_STAR ) })
20872095 case AT if ! location.inPattern =>
20882096 annotations().foldLeft(t)(Annotated )
20892097 case _ =>
@@ -2200,10 +2208,18 @@ object Parsers {
22002208 * | InfixExpr id [nl] InfixExpr
22012209 * | InfixExpr MatchClause
22022210 */
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
22042217
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 )
22072223
22082224 /** PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr
22092225 */
@@ -2331,7 +2347,7 @@ object Parsers {
23312347 if (in.token == RPAREN ) Nil else commaSeparated(exprInParens)
23322348
23332349 /** ParArgumentExprs ::= `(' [‘using’] [ExprsInParens] `)'
2334- * | `(' [ExprsInParens `,'] PostfixExpr `:' `_' ` *' ')'
2350+ * | `(' [ExprsInParens `,'] PostfixExpr `*' ')'
23352351 */
23362352 def parArgumentExprs (): (List [Tree ], Boolean ) = inParens {
23372353 if in.token == RPAREN then
@@ -2614,7 +2630,7 @@ object Parsers {
26142630 */
26152631 def pattern3 (): Tree =
26162632 val p = infixPattern()
2617- if isPostfixStar then
2633+ if followingIsVararg() then
26182634 atSpan(in.skipToken()) {
26192635 Typed (p, Ident (tpnme.WILDCARD_STAR ))
26202636 }
@@ -2646,7 +2662,8 @@ object Parsers {
26462662 */
26472663 def infixPattern (): Tree =
26482664 infixOps(simplePattern(), in.canStartExprTokens, simplePattern,
2649- isOperator = in.name != nme.raw.BAR && ! isPostfixStar)
2665+ isType = false ,
2666+ isOperator = in.name != nme.raw.BAR && ! followingIsVararg())
26502667
26512668 /** SimplePattern ::= PatVar
26522669 * | Literal
0 commit comments