aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala22
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala12
-rw-r--r--compiler/test/dotc/tests.scala3
-rw-r--r--tests/neg/varargsInMethodsT1625/allParamsAreVarArgs.scala3
-rw-r--r--tests/neg/varargsInMethodsT1625/caseClassConstructorVarArgs.scala3
-rw-r--r--tests/neg/varargsInMethodsT1625/classConstructorVarArgs.scala3
-rw-r--r--tests/neg/varargsInMethodsT1625/curriedNegExample.scala3
-rw-r--r--tests/neg/varargsInMethodsT1625/firstParamIsVarArgs.scala3
-rw-r--r--tests/pos/varargsInMethodsT1625/curriedPosExample.scala3
-rw-r--r--tests/pos/varargsInMethodsT1625/onlyOneVarArgs.scala3
10 files changed, 57 insertions, 1 deletions
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index 65c7a290d..b644c94cc 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -12,7 +12,7 @@ import core._
import Flags._
import Contexts._
import Names._
-import ast.Positioned
+import ast.{Positioned, Trees, untpd}
import ast.Trees._
import Decorators._
import StdNames._
@@ -20,6 +20,7 @@ import util.Positions._
import Constants._
import ScriptParsers._
import Comments._
+
import scala.annotation.{tailrec, switch}
import util.DotClass
import rewrite.Rewrites.patch
@@ -1800,6 +1801,10 @@ object Parsers {
case _ => syntaxError(AuxConstructorNeedsNonImplicitParameter(), start)
}
}
+ val listOfErrors = checkVarArgsRules(result)
+ listOfErrors.foreach { vparam =>
+ syntaxError(VarArgsParamMustComeLast(), vparam.tpt.pos)
+ }
result
}
@@ -1921,6 +1926,21 @@ object Parsers {
}
}
+
+
+ private def checkVarArgsRules(vparamss: List[List[untpd.ValDef]]): List[untpd.ValDef] = {
+ def isVarArgs(tpt: Trees.Tree[Untyped]): Boolean = tpt match {
+ case PostfixOp(_, op) if op.name == nme.raw.STAR => true
+ case _ => false
+ }
+
+ vparamss.flatMap { params =>
+ if (params.nonEmpty) {
+ params.init.filter(valDef => isVarArgs(valDef.tpt))
+ } else List()
+ }
+ }
+
/** DefDef ::= DefSig (`:' Type [`=' Expr] | "=" Expr)
* | this ParamClause ParamClauses `=' ConstrExpr
* DefDcl ::= DefSig `:' Type
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 6fa056646..57365658e 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -1209,4 +1209,16 @@ object messages {
|${parents.mkString(" - ", "\n - ", "")}
|""".stripMargin
}
+
+ case class VarArgsParamMustComeLast()(implicit ctx: Context)
+ extends Message(IncorrectRepeatedParameterSyntaxID) {
+ override def msg: String = "varargs parameter must come last"
+
+ override def kind: String = "Syntax"
+
+ override def explanation: String =
+ hl"""|The varargs field must be the last field in the method signature.
+ |Attempting to define a field in a method signature after a varargs field is an error.
+ |""".stripMargin
+ }
}
diff --git a/compiler/test/dotc/tests.scala b/compiler/test/dotc/tests.scala
index 01db2d9cc..3ebf7f2c4 100644
--- a/compiler/test/dotc/tests.scala
+++ b/compiler/test/dotc/tests.scala
@@ -153,6 +153,7 @@ class tests extends CompilerTest {
@Test def pos_anonClassSubtyping = compileFile(posDir, "anonClassSubtyping", twice)
@Test def pos_extmethods = compileFile(posDir, "extmethods", twice)
@Test def pos_companions = compileFile(posDir, "companions", twice)
+ @Test def posVarargsT1625 = compileFiles(posDir + "varargsInMethodsT1625/")
@Test def pos_all = compileFiles(posDir) // twice omitted to make tests run faster
@@ -177,6 +178,8 @@ class tests extends CompilerTest {
@Test def neg_all = compileFiles(negDir, verbose = true, compileSubDirs = false)
@Test def neg_typedIdents() = compileDir(negDir, "typedIdents")
+ @Test def negVarargsT1625 = compileFiles(negDir + "varargsInMethodsT1625/")
+
val negCustomArgs = negDir + "customArgs/"
@Test def neg_typers() = compileFile(negCustomArgs, "typers")(allowDoubleBindings)
diff --git a/tests/neg/varargsInMethodsT1625/allParamsAreVarArgs.scala b/tests/neg/varargsInMethodsT1625/allParamsAreVarArgs.scala
new file mode 100644
index 000000000..aabb1ecea
--- /dev/null
+++ b/tests/neg/varargsInMethodsT1625/allParamsAreVarArgs.scala
@@ -0,0 +1,3 @@
+trait T3 {
+ def foo(x: String*, y: String*, c: String*): Int // error // error: varargs parameter must come last
+} \ No newline at end of file
diff --git a/tests/neg/varargsInMethodsT1625/caseClassConstructorVarArgs.scala b/tests/neg/varargsInMethodsT1625/caseClassConstructorVarArgs.scala
new file mode 100644
index 000000000..8f8a4fcf6
--- /dev/null
+++ b/tests/neg/varargsInMethodsT1625/caseClassConstructorVarArgs.scala
@@ -0,0 +1,3 @@
+object T5 {
+ case class Abc(x: String*, c: String*) // error //error: varargs parameter must come last AND found: String* required: String
+} \ No newline at end of file
diff --git a/tests/neg/varargsInMethodsT1625/classConstructorVarArgs.scala b/tests/neg/varargsInMethodsT1625/classConstructorVarArgs.scala
new file mode 100644
index 000000000..74595cb7d
--- /dev/null
+++ b/tests/neg/varargsInMethodsT1625/classConstructorVarArgs.scala
@@ -0,0 +1,3 @@
+class Abc(val x: String*, val c: String*) { // error: varargs parameter must come last
+ def test = ???
+} \ No newline at end of file
diff --git a/tests/neg/varargsInMethodsT1625/curriedNegExample.scala b/tests/neg/varargsInMethodsT1625/curriedNegExample.scala
new file mode 100644
index 000000000..616ea0539
--- /dev/null
+++ b/tests/neg/varargsInMethodsT1625/curriedNegExample.scala
@@ -0,0 +1,3 @@
+trait T2 {
+ def foo(x: String*, y: String*)(z: Boolean*)(u: Int*, l: Int*): Int // error // error: varargs parameter must come last
+} \ No newline at end of file
diff --git a/tests/neg/varargsInMethodsT1625/firstParamIsVarArgs.scala b/tests/neg/varargsInMethodsT1625/firstParamIsVarArgs.scala
new file mode 100644
index 000000000..eceb7e696
--- /dev/null
+++ b/tests/neg/varargsInMethodsT1625/firstParamIsVarArgs.scala
@@ -0,0 +1,3 @@
+trait T1 {
+ def foo(x: String*, y: String): Int // error: varargs parameter must come last
+} \ No newline at end of file
diff --git a/tests/pos/varargsInMethodsT1625/curriedPosExample.scala b/tests/pos/varargsInMethodsT1625/curriedPosExample.scala
new file mode 100644
index 000000000..c614f2dee
--- /dev/null
+++ b/tests/pos/varargsInMethodsT1625/curriedPosExample.scala
@@ -0,0 +1,3 @@
+trait T2 {
+ def foo(x: String, y: String*)(z: Boolean*)(u: Int, l: Int*): Int
+} \ No newline at end of file
diff --git a/tests/pos/varargsInMethodsT1625/onlyOneVarArgs.scala b/tests/pos/varargsInMethodsT1625/onlyOneVarArgs.scala
new file mode 100644
index 000000000..834960b4a
--- /dev/null
+++ b/tests/pos/varargsInMethodsT1625/onlyOneVarArgs.scala
@@ -0,0 +1,3 @@
+trait T1 {
+ def foo(x: String*): Int
+} \ No newline at end of file