summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala18
-rw-r--r--test/files/jvm/varargs.check3
-rw-r--r--test/files/jvm/varargs/JavaClass.java1
-rw-r--r--test/files/jvm/varargs/VaClass.scala1
-rw-r--r--test/files/neg/varargs.check9
-rw-r--r--test/files/neg/varargs.scala9
6 files changed, 33 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index d1a4672805..7538043d8f 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -734,11 +734,20 @@ abstract class UnCurry extends InfoTransform with TypingTransformers with ast.Tr
*/
private def addJavaVarargsForwarders(dd: DefDef, flatdd: DefDef, tree: Tree) = if (repeatedParams.contains(dd.symbol)) {
def toArrayType(tp: Type): Type = tp match {
- case TypeRef(_, SeqClass, List(tparg)) => arrayType(tparg)
+ case TypeRef(_, SeqClass, List(tparg)) =>
+ // to prevent generation of an `Object` parameter from `Array[T]` parameter later
+ // as this would crash the Java compiler which expects an `Object[]` array for varargs
+ // e.g. def foo[T](a: Int, b: T*)
+ // becomes def foo[T](a: Int, b: Array[Object])
+ // instead of def foo[T](a: Int, b: Array[T]) ===> def foo[T](a: Int, b: Object)
+ if (tparg.typeSymbol.isTypeSkolem) arrayType(ObjectClass.tpe) else arrayType(tparg)
}
def toSeqType(tp: Type): Type = tp match {
case TypeRef(_, ArrayClass, List(tparg)) => seqType(tparg)
}
+ def seqElemType(tp: Type): Type = tp match {
+ case TypeRef(_, SeqClass, List(tparg)) => tparg
+ }
def arrayElemType(tp: Type): Type = tp match {
case TypeRef(_, ArrayClass, List(tparg)) => tparg
}
@@ -772,7 +781,10 @@ abstract class UnCurry extends InfoTransform with TypingTransformers with ast.Tr
val locals: List[ValDef] = for ((argsym, fp) <- (forwsym ARGS) zip flatparams) yield
if (rpsymbols contains fp.symbol)
VAL(forwsym.newValue(unit.fresh.newName("param$")).setInfo(fp.symbol.tpe)) === {
- gen.mkWrapArray(Ident(argsym), arrayElemType(argsym.tpe))
+ gen.mkCast(
+ gen.mkWrapArray(Ident(argsym), arrayElemType(argsym.tpe)),
+ seqType(seqElemType(fp.symbol.tpe))
+ )
}
else null
val emitted = for (l <- locals if l != null) yield l
@@ -791,7 +803,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers with ast.Tr
}
// check if the method with that name and those arguments already exists in the template
- currentClass.info.decls.lookupAll(forwsym.name).find(s => s != forwsym && s.tpe.matches(forwsym.tpe)) match {
+ currentClass.info.member(forwsym.name).alternatives.find(s => s != forwsym && s.tpe.matches(forwsym.tpe)) match {
case Some(s) => unit.error(dd.symbol.pos,
"A method with a varargs annotation produces a forwarder method with the same signature "
+ s.tpe + " as an existing method.")
diff --git a/test/files/jvm/varargs.check b/test/files/jvm/varargs.check
index fef7448acb..8379befe93 100644
--- a/test/files/jvm/varargs.check
+++ b/test/files/jvm/varargs.check
@@ -1,2 +1,3 @@
7
-10 \ No newline at end of file
+10
+19 \ No newline at end of file
diff --git a/test/files/jvm/varargs/JavaClass.java b/test/files/jvm/varargs/JavaClass.java
index b5158f2878..9851e1b78b 100644
--- a/test/files/jvm/varargs/JavaClass.java
+++ b/test/files/jvm/varargs/JavaClass.java
@@ -10,5 +10,6 @@ public class JavaClass {
va.vs(4, "", "", "");
va.vi(1, 2, 3, 4);
varargz(5, 1.0, 2.0, 3.0);
+ va.vt(16, "", "", "");
}
} \ No newline at end of file
diff --git a/test/files/jvm/varargs/VaClass.scala b/test/files/jvm/varargs/VaClass.scala
index ffa25027d3..6343f9c6f6 100644
--- a/test/files/jvm/varargs/VaClass.scala
+++ b/test/files/jvm/varargs/VaClass.scala
@@ -8,5 +8,6 @@ class VaClass {
@varargs def vs(a: Int, b: String*) = println(a + b.length)
@varargs def vi(a: Int, b: Int*) = println(a + b.sum)
+ @varargs def vt[T](a: Int, b: T*) = println(a + b.length)
}
diff --git a/test/files/neg/varargs.check b/test/files/neg/varargs.check
index f3254708b8..1352dd968c 100644
--- a/test/files/neg/varargs.check
+++ b/test/files/neg/varargs.check
@@ -1,7 +1,10 @@
-varargs.scala:11: error: A method without repeated parameters cannot be annotated with the `varargs` annotation.
+varargs.scala:16: error: A method with a varargs annotation produces a forwarder method with the same signature (a: Int,b: Array[java.lang.String])Int as an existing method.
+ @varargs def v1(a: Int, b: String*) = a + b.length
+ ^
+varargs.scala:19: error: A method without repeated parameters cannot be annotated with the `varargs` annotation.
@varargs def nov(a: Int) = 0
^
-varargs.scala:13: error: A method with a varargs annotation produces a forwarder method with the same signature (a: Int,b: Array[java.lang.String])Int as an existing method.
+varargs.scala:21: error: A method with a varargs annotation produces a forwarder method with the same signature (a: Int,b: Array[java.lang.String])Int as an existing method.
@varargs def v2(a: Int, b: String*) = 0
^
-two errors found \ No newline at end of file
+three errors found \ No newline at end of file
diff --git a/test/files/neg/varargs.scala b/test/files/neg/varargs.scala
index a2f895a87d..be75e9b0a7 100644
--- a/test/files/neg/varargs.scala
+++ b/test/files/neg/varargs.scala
@@ -8,13 +8,20 @@ import annotation.varargs
// Failing varargs annotation
object Test {
+ trait A {
+ def v1(a: Int, b: Array[String]) = a
+ }
+
+ trait B extends A {
+ @varargs def v1(a: Int, b: String*) = a + b.length
+ }
+
@varargs def nov(a: Int) = 0
@varargs def v(a: Int, b: String*) = a + b.length
@varargs def v2(a: Int, b: String*) = 0
def v2(a: Int, b: Array[String]) = 0
def main(args: Array[String]) {
-
}
}