From d36bb52ad293a675a1df49cb88f23f22b5ac6204 Mon Sep 17 00:00:00 2001 From: Lucas Nouguier Date: Tue, 11 Jul 2023 17:44:15 +0200 Subject: [PATCH] added check for repeated params in using clause refactor and more tests Update error message Co-authored-by: Nicolas Stucki fix error code --- .../dotty/tools/dotc/parsing/Parsers.scala | 6 ++- .../tools/dotc/reporting/ErrorMessageID.scala | 1 + .../dotty/tools/dotc/reporting/messages.scala | 8 ++++ tests/neg/i18090.check | 42 +++++++++++++++++++ tests/neg/i18090.scala | 10 +++++ 5 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/neg/i18090.check create mode 100644 tests/neg/i18090.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 71c3fd9c43bd..f3a8a1ace8fd 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -3334,11 +3334,13 @@ object Parsers { def checkVarArgsRules(vparams: List[ValDef]): Unit = vparams match { case Nil => - case _ :: Nil if !prefix => case vparam :: rest => vparam.tpt match { case PostfixOp(_, op) if op.name == tpnme.raw.STAR => - syntaxError(VarArgsParamMustComeLast(), vparam.tpt.span) + if vparam.mods.isOneOf(GivenOrImplicit) then + syntaxError(VarArgsParamCannotBeGiven(vparam.mods.is(Given)), vparam.tpt.span) + if rest.nonEmpty then + syntaxError(VarArgsParamMustComeLast(), vparam.tpt.span) case _ => } checkVarArgsRules(rest) diff --git a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala index e5cdc3311e37..5cbe336acc28 100644 --- a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala +++ b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala @@ -201,6 +201,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe case UnimportedAndImportedID // errorNumber: 185 case ImplausiblePatternWarningID // erorNumber: 186 case SynchronizedCallOnBoxedClassID // errorNumber: 187 + case VarArgsParamCannotBeGivenID // erorNumber: 188 def errorNumber = ordinal - 1 diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index e194f3740003..b482afc5e9b3 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -1319,6 +1319,14 @@ extends SyntaxMsg(VarArgsParamMustComeLastID) { |""" } +class VarArgsParamCannotBeGiven(isGiven: Boolean)(using Context) +extends SyntaxMsg(VarArgsParamCannotBeGivenID) { + def msg(using Context) = i"repeated parameters are not allowed in a ${if isGiven then "using" else "implicit"} clause" + def explain(using Context) = + "It is not possible to define a given with a repeated parameter type. This hypothetical given parameter could always be satisfied by providing 0 arguments, which defeats the purpose of a given argument." +} + + import typer.Typer.BindingPrec class ConstrProxyShadows(proxy: TermRef, shadowed: Type, shadowedIsApply: Boolean)(using Context) diff --git a/tests/neg/i18090.check b/tests/neg/i18090.check new file mode 100644 index 000000000000..fe61a3337acf --- /dev/null +++ b/tests/neg/i18090.check @@ -0,0 +1,42 @@ +-- [E188] Syntax Error: tests/neg/i18090.scala:2:18 -------------------------------------------------------------------- +2 |def foo(using xs: Int*) = xs // error + | ^^^^ + | repeated parameters are not allowed in a using clause + | + | longer explanation available when compiling with `-explain` +-- [E188] Syntax Error: tests/neg/i18090.scala:3:27 -------------------------------------------------------------------- +3 |def foo5(using d: Int, xs: Int*) = xs // error + | ^^^^ + | repeated parameters are not allowed in a using clause + | + | longer explanation available when compiling with `-explain` +-- [E188] Syntax Error: tests/neg/i18090.scala:4:22 -------------------------------------------------------------------- +4 |def foo2(implicit xs: Int*) = xs // error + | ^^^^ + | repeated parameters are not allowed in a implicit clause + | + | longer explanation available when compiling with `-explain` +-- [E188] Syntax Error: tests/neg/i18090.scala:5:35 -------------------------------------------------------------------- +5 |def foo3(u: Int)(using d: Int, xs: Int*) = xs // error + | ^^^^ + | repeated parameters are not allowed in a using clause + | + | longer explanation available when compiling with `-explain` +-- [E188] Syntax Error: tests/neg/i18090.scala:6:38 -------------------------------------------------------------------- +6 |def foo4(u: Int)(implicit d: Int, xs: Int*) = xs // error + | ^^^^ + | repeated parameters are not allowed in a implicit clause + | + | longer explanation available when compiling with `-explain` +-- [E188] Syntax Error: tests/neg/i18090.scala:9:20 -------------------------------------------------------------------- +9 | def bar(using xs: Float*) = ??? // error + | ^^^^^^ + | repeated parameters are not allowed in a using clause + | + | longer explanation available when compiling with `-explain` +-- [E188] Syntax Error: tests/neg/i18090.scala:10:33 ------------------------------------------------------------------- +10 | def bar2(using d: Boolean, xs: Float*) = ??? // error + | ^^^^^^ + | repeated parameters are not allowed in a using clause + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i18090.scala b/tests/neg/i18090.scala new file mode 100644 index 000000000000..05c0df65c3b1 --- /dev/null +++ b/tests/neg/i18090.scala @@ -0,0 +1,10 @@ + +def foo(using xs: Int*) = xs // error +def foo5(using d: Int, xs: Int*) = xs // error +def foo2(implicit xs: Int*) = xs // error +def foo3(u: Int)(using d: Int, xs: Int*) = xs // error +def foo4(u: Int)(implicit d: Int, xs: Int*) = xs // error + +extension (i: Int) + def bar(using xs: Float*) = ??? // error + def bar2(using d: Boolean, xs: Float*) = ??? // error