Skip to content

Commit dbb98b3

Browse files
committed
Don't drop Object intersection for varargs
A Java generic array `T[]` is unpickled in ClassfileParser to `Array[T & Object]`, because it will not accept primitive arrays. However, Java varargs were special-cased to drop this intersection. Erasure contained some code to compensate for this, but this is still unsound and lead to tests/run/t1360.scala failing with a ClassCastException. Thanks to scala#8669 we can drop this special-casing of varargs without affecting typing too much: it's still possible to pass `Array(1, 2): _*` where `(T & Object)*` is expected because adaptation will take care of boxing. One test case had to be adapted, I replaced: def apply[X](xs : X*): java.util.List[X] java.util.Arrays.asList(xs: _*) with: def apply[X <: AnyRef](xs : X*): java.util.List[X] = java.util.Arrays.asList(xs: _*) I don't think that's too constraining. Note: after this commit, tests/run/i533 started failing, this is fixed in the next commit.
1 parent c80d6e4 commit dbb98b3

File tree

5 files changed

+7
-20
lines changed

5 files changed

+7
-20
lines changed

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,9 @@ object Scala2Unpickler {
6767
case tp: MethodType =>
6868
val lastArg = tp.paramInfos.last
6969
assert(lastArg isRef defn.ArrayClass)
70-
val elemtp0 :: Nil = lastArg.baseType(defn.ArrayClass).argInfos
71-
val elemtp = elemtp0 match {
72-
case AndType(t1, t2) => // drop intersection with Object for abstract types and parameters in varargs. Erasure can handle them.
73-
if t2.isAnyRef then
74-
t1 match {
75-
case t1: TypeParamRef => t1
76-
case t1: TypeRef if t1.symbol.isAbstractOrParamType => t1
77-
case _ => elemtp0
78-
}
79-
else elemtp0
80-
case _ =>
81-
elemtp0
82-
}
8370
tp.derivedLambdaType(
8471
tp.paramNames,
85-
tp.paramInfos.init :+ defn.RepeatedParamType.appliedTo(elemtp),
72+
tp.paramInfos.init :+ lastArg.translateParameterized(defn.ArrayClass, defn.RepeatedParamClass),
8673
tp.resultType)
8774
case tp: PolyType =>
8875
tp.derivedLambdaType(tp.paramNames, tp.paramInfos, arrayToRepeated(tp.resultType))

compiler/src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,6 @@ object Erasure {
309309
assert(!pt.isInstanceOf[SingletonType], pt)
310310
if (pt isRef defn.UnitClass) unbox(tree, pt)
311311
else (tree.tpe.widen, pt) match {
312-
case (JavaArrayType(treeElem), JavaArrayType(ptElem))
313-
if treeElem.widen.isPrimitiveValueType && !ptElem.isPrimitiveValueType =>
314-
// See SI-2386 for one example of when this might be necessary.
315-
cast(ref(defn.runtimeMethodRef(nme.toObjectArray)).appliedTo(tree), pt)
316-
317312
// When casting between two EVTs, we need to check which one underlies the other to determine
318313
// whether u2evt or evt2u should be used.
319314
case (tp1 @ ErasedValueType(tycon1, underlying1), tp2 @ ErasedValueType(tycon2, underlying2)) =>

tests/pos/arrays2.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ one warning found
2323

2424
// #2461
2525
object arrays3 {
26-
def apply[X](xs : X*) : java.util.List[X] = java.util.Arrays.asList(xs: _*)
26+
def apply[X <: AnyRef](xs : X*) : java.util.List[X] = java.util.Arrays.asList(xs: _*)
2727
}

tests/run/java-varargs/A_1.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
class A_1 {
22
public static void foo(int... args) {
33
}
4+
5+
public static <T> void gen(T... args) {
6+
}
47
}

tests/run/java-varargs/Test_2.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@ object Test {
22
def main(args: Array[String]): Unit = {
33
A_1.foo(Array(1): _*)
44
A_1.foo(Seq(1): _*)
5+
A_1.gen(Array(1): _*)
6+
A_1.gen(Seq(1): _*)
57
}
68
}

0 commit comments

Comments
 (0)