Skip to content

Commit 5581cdb

Browse files
committed
More words for misused using
1 parent fd45847 commit 5581cdb

File tree

5 files changed

+281
-9
lines changed

5 files changed

+281
-9
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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}

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ extends NotFoundMsg(MissingIdentID) {
287287
|imported from elsewhere.
288288
|
289289
|Possible reasons why no matching declaration was found:
290-
| - The declaration or the use is mis-spelt.
290+
| - The declaration or the use is misspelled.
291291
| - An import is missing."""
292292
}
293293
}
@@ -1221,6 +1221,17 @@ extends SyntaxMsg(ExpectedTokenButFoundID) {
12211221
""
12221222
}
12231223

1224+
class ExpectedTokenButFoundSoftKeyword(expected: Token, found: Token, soft: Name, advice: String = "")(using Context)
1225+
extends SyntaxMsg(ExpectedTokenButFoundID):
1226+
def addendum = if !advice.isEmpty then s"\n$advice" else advice
1227+
def msg(using Context) =
1228+
val expectedText = if Tokens.isIdentifier(expected) then "an identifier" else Tokens.showToken(expected)
1229+
val what = if Tokens.isIdentifier(found) || expected == Tokens.COLONop then "an identifier" else "the soft keyword"
1230+
s"""$expectedText expected, but ${Tokens.showToken(found)} found.
1231+
|The soft keyword `$soft` was taken as $what in this context.$addendum""".stripMargin
1232+
def explain(using Context) = s"The soft keyword `$soft` has special meaning only in certain contexts.$addendum"
1233+
end ExpectedTokenButFoundSoftKeyword
1234+
12241235
class MixedLeftAndRightAssociativeOps(op1: Name, op2: Name, op2LeftAssoc: Boolean)(using Context)
12251236
extends SyntaxMsg(MixedLeftAndRightAssociativeOpsID) {
12261237
def msg(using Context) =

compiler/test/dotty/tools/vulpix/ParallelTesting.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,12 @@ trait ParallelTesting extends RunnerOrchestration { self =>
935935

936936
Option {
937937
if actualErrors == 0 then s"\nNo errors found when compiling neg test $testSource"
938-
else if expectedErrors == 0 then s"\nNo errors expected/defined in $testSource -- use // error or // nopos-error"
938+
else if expectedErrors == 0 then
939+
s"""|No expected errors marked in $testSource -- use // error or // nopos-error
940+
|actual error count: $actualErrors
941+
|${unexpected.mkString("Unexpected errors:\n", "\n", "")}
942+
|$showErrors
943+
|""".stripMargin.trim.linesIterator.mkString("\n", "\n", "")
939944
else if expectedErrors != actualErrors then
940945
s"""|Wrong number of errors encountered when compiling $testSource
941946
|expected: $expectedErrors, actual: $actualErrors

0 commit comments

Comments
 (0)