Skip to content

Commit c80d6e4

Browse files
committed
Fix ClassCastException with Java primitive varargs
The class constant corresponding to the primitive type `int` is represented in bytecode by `Integer.TYPE`, this is correctly handled when calling `clsOf`, but so far `ElimRepeated` was manually creating a constant instead which does not work (I've now changed the backend to emit a failure instead of doing the wrong thing when someone does that, I also plan to rework the way we handle classOf to make this less error-prone). Note: after this commit, tests/run/t1360.scala started failing, this is fixed in the next commit.
1 parent c7fb0fc commit c80d6e4

File tree

4 files changed

+15
-8
lines changed

4 files changed

+15
-8
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -483,13 +483,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
483483
case NullTag => emit(asm.Opcodes.ACONST_NULL)
484484

485485
case ClazzTag =>
486-
val toPush: BType = {
487-
toTypeKind(const.typeValue) match {
488-
case kind: PrimitiveBType => boxedClassOfPrimitive(kind)
489-
case kind => kind
490-
}
491-
}
492-
mnode.visitLdcInsn(toPush.toASMType)
486+
val tp = toTypeKind(const.typeValue)
487+
// classOf[Int] is transformed to Integer.TYPE by ClassOf
488+
assert(!tp.isPrimitive, s"expected class type in classOf[T], found primitive type $tp")
489+
mnode.visitLdcInsn(tp.toASMType)
493490

494491
case EnumTag =>
495492
val sym = const.symbolValue

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
9999
ref(defn.DottyArraysModule)
100100
.select(nme.seqToArray)
101101
.appliedToType(elemType)
102-
.appliedTo(tree, Literal(Constant(elemClass.typeRef)))
102+
.appliedTo(tree, clsOf(elemClass.typeRef))
103103
}
104104

105105
/** Convert Java array argument to Scala Seq */

tests/run/java-varargs/A_1.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class A_1 {
2+
public static void foo(int... args) {
3+
}
4+
}

tests/run/java-varargs/Test_2.scala

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

0 commit comments

Comments
 (0)