Skip to content

Unspecialized method on a @specialized class calls AnyRef variant of method with an Array[E @uncheckedVariance] argument (and not erased). #12951

Open
@noresttherein

Description

@noresttherein

Reproduction steps

Scala version: 2.13.12

trait Ops[@specialized(Int) +T, C] {
	protected[this] def array :Array[T]
	def copy :C = fromSpecific(array)
	def fromSpecific(array :Array[T @uncheckedVariance]) :C
}

class Spec[@specialized(Int) T](val array :Array[T]) extends Ops[T, Spec[T]] {
	override def fromSpecific(array :Array[T]) :Spec[T] = new Spec(array)
}

object app extends App {
	val spec = new Spec(Array(1, 2))
	spec.copy
}

Problem

Exception in thread "main" java.lang.ClassCastException: class [I cannot be cast to class [Ljava.lang.Object; ([I and [Ljava.lang.Object; are in module java.base of loader 'bootstrap')
	at Ops.copy(Playground.scala:17)
	at Ops.copy$(Playground.scala:17)
	at Spec.copy(Playground.scala:21)
	at Playground$.delayedEndpoint$Playground$1(Playground.scala:27)
	at Playground$delayedInit$body.apply(Playground.scala:25)
	at scala.Function0.apply$mcV$sp(Function0.scala:42)
	at scala.Function0.apply$mcV$sp$(Function0.scala:42)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
	at scala.App.$anonfun$main$1(App.scala:98)
	at scala.App.$anonfun$main$1$adapted(App.scala:98)
	at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:576)
	at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:574)
	at scala.collection.AbstractIterable.foreach(Iterable.scala:933)

Output from javap:

public class Spec<T> implements Ops<T, Spec<T>> {
  public final java.lang.Object array;
  public java.lang.Object copy();
  public java.lang.Object array();
  public Spec<T> fromSpecific(java.lang.Object);
  public int[] array$mcI$sp();
  public Spec<java.lang.Object> fromSpecific$mcI$sp(int[]);
  public boolean specInstance$();
  public java.lang.Object fromSpecific$mcI$sp(int[]);
  public java.lang.Object fromSpecific(java.lang.Object[]);
  public Spec(java.lang.Object);
}

The line counts are off; I have not looked into raw bytecode, but it seems to me that copy calls fromSpecific(Object[]) rather than fromSpecific(Object).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions