@@ -213,7 +213,7 @@ object Parsers {
213213 def isIdent (name : Name ) = in.isIdent(name)
214214 def isPureArrow (name : Name ): Boolean = isIdent(name) && Feature .pureFunsEnabled
215215 def isPureArrow : Boolean = isPureArrow(nme.PUREARROW ) || isPureArrow(nme.PURECTXARROW )
216- def isErased = isIdent(nme.erased) && in.erasedEnabled
216+ def isErased = in.isErased
217217 // Are we seeing an `erased` soft keyword that will not be an identifier?
218218 def isErasedKw = isErased && in.isSoftModifierInParamModifierPosition
219219 def isSimpleLiteral =
@@ -3503,15 +3503,19 @@ object Parsers {
35033503
35043504 def addParamMod (mod : () => Mod ) = impliedMods = addMod(impliedMods, atSpan(in.skipToken()) { mod() })
35053505
3506+ def paramModAdvice = " It is a keyword only at the beginning of a parameter clause."
3507+
35063508 def paramMods () =
35073509 if in.token == IMPLICIT then
35083510 addParamMod(() => Mod .Implicit ())
35093511 else if isIdent(nme.using) then
35103512 if initialMods.is(Given ) then
35113513 syntaxError(em " `using` is already implied here, should not be given explicitly " , in.offset)
35123514 addParamMod(() => Mod .Given ())
3515+ if in.isColon then
3516+ syntaxErrorOrIncomplete(ExpectedTokenButFoundSoftKeyword (IDENTIFIER , COLONop , nme.using, paramModAdvice))
35133517
3514- def param (): ValDef = {
3518+ def param (): ValDef =
35153519 val start = in.offset
35163520 var mods = impliedMods.withAnnotations(annotations())
35173521 if isErasedKw then
@@ -3538,9 +3542,21 @@ object Parsers {
35383542 mods |= Param
35393543 }
35403544 atSpan(start, nameStart) {
3541- val name = ident()
3542- acceptColon()
3543- if (in.token == ARROW && paramOwner.isClass && ! mods.is(Local ))
3545+ val name = ident() match
3546+ case nme.using if ! in.isColon =>
3547+ val msg = ExpectedTokenButFoundSoftKeyword (expected = COLONop , found = in.token, nme.using, paramModAdvice)
3548+ val span = Span (in.offset, in.offset + (if in.name != null then in.name.show.length else 0 ))
3549+ val pickOne =
3550+ if in.token == IDENTIFIER then
3551+ while in.isSoftModifierInParamModifierPosition do ident() // skip to intended name, discard mods
3552+ ident()
3553+ else nme.using
3554+ syntaxErrorOrIncomplete(msg, span)
3555+ pickOne
3556+ case name =>
3557+ acceptColon()
3558+ name
3559+ if in.token == ARROW && paramOwner.isClass && ! mods.is(Local ) then
35443560 syntaxError(VarValParametersMayNotBeCallByName (name, mods.is(Mutable )))
35453561 // needed?, it's checked later anyway
35463562 val tpt = paramType()
@@ -3551,7 +3567,7 @@ object Parsers {
35513567 impliedMods = impliedMods.withMods(Nil ) // keep only flags, so that parameter positions don't overlap
35523568 ValDef (name, tpt, default).withMods(mods)
35533569 }
3554- }
3570+ end param
35553571
35563572 def checkVarArgsRules (vparams : List [ValDef ]): Unit = vparams match {
35573573 case Nil =>
@@ -3601,11 +3617,13 @@ object Parsers {
36013617 else contextTypes(paramOwner, numLeadParams, impliedMods)
36023618 params match
36033619 case Nil => Nil
3604- case (h :: t) => h.withAddedFlags(firstParamMod.flags) :: t
3620+ case h :: t => h.withAddedFlags(firstParamMod.flags) :: t
3621+ end clause
36053622 checkVarArgsRules(clause)
36063623 clause
36073624 }
36083625 }
3626+ end termParamClause
36093627
36103628 /** ClsTermParamClauses ::= {ClsTermParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’]
36113629 * TypelessClauses ::= TypelessClause {TypelessClause}
0 commit comments