diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 18 | ||||
-rw-r--r-- | test/files/jvm/varargs.check | 3 | ||||
-rw-r--r-- | test/files/jvm/varargs/JavaClass.java | 1 | ||||
-rw-r--r-- | test/files/jvm/varargs/VaClass.scala | 1 | ||||
-rw-r--r-- | test/files/neg/varargs.check | 9 | ||||
-rw-r--r-- | test/files/neg/varargs.scala | 9 |
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]) { - } } |