Closed
Description
Interaction with specialization
Specialization adds another small challenge. In the example below, notice how apply : (Int)V
has been added to the specialized sub interface. A Java subclass of T$mcI$sp
would need to implement both apply
-s. T$mcI$sp
is not a functional interface, so can't be used in LambdaMetafactory
/ (e.g. as the target type of a Java lambda expressions).
We run straight into this problem with the specialized Scala function traits.
% cat sandbox/spec.scala
trait T[@specialized A] {
def t(a: A): Unit
}
% scalac sandbox/spec.scala && javap -classpath . T 'T$mcI$sp'
Compiled from "spec.scala"
public interface T{
public abstract void t(java.lang.Object);
public abstract void t$mcZ$sp(boolean);
public abstract void t$mcB$sp(byte);
public abstract void t$mcC$sp(char);
public abstract void t$mcD$sp(double);
public abstract void t$mcF$sp(float);
public abstract void t$mcI$sp(int);
public abstract void t$mcJ$sp(long);
public abstract void t$mcS$sp(short);
public abstract void t$mcV$sp(scala.runtime.BoxedUnit);
}
Compiled from "spec.scala"
public interface T$mcI$sp extends T{
public abstract void t(int);
}
Contrast with a regular trait that inherits another trait:
cat sandbox/spec.scala && scalac sandbox/spec.scala && javap -classpath . U V
trait U[A] {
def t(a: A): Unit
}
trait V extends U[Int]
Compiled from "spec.scala"
public interface U{
public abstract void t(java.lang.Object);
}
Compiled from "spec.scala"
public interface V extends U{
}
We should investigate whether addition of this method by specialization is necessary / intentional. If we cannot omit it, we do have the possibility to bridge it.
public interface T$mcI$sp extends T{
public abstract void t(int) = UNBOX(t$mcI$sp(BOX(arg)))
}
Scala callers never route into this method:
% cat sandbox/spec.scala && scalac sandbox/spec.scala && javap -c -classpath . Client
trait T[@specialized -A] {
def t(a: A): Unit
}
class Client {
def f(tint: T[Int])= tint.t(0)
def g[A](t: T[A], a: A) = t.t(a)
}
Compiled from "spec.scala"
public class Client extends java.lang.Object{
public void f(T);
Code:
0: aload_1
1: iconst_0
2: invokeinterface #16, 2; //InterfaceMethod T.t$mcI$sp:(I)V
7: return
public void g(T, java.lang.Object);
Code:
0: aload_1
1: aload_2
2: invokeinterface #26, 2; //InterfaceMethod T.t:(Ljava/lang/Object;)V
7: return
public Client();
Code:
0: aload_0
1: invokespecial #32; //Method java/lang/Object."<init>":()V
4: return
}