8000 SI-1459 two bridges for impl of java generic vararg method · scala/scala@83b0826 · GitHub
[go: up one dir, main page]

Skip to content

Commit 83b0826

Browse files
committed
SI-1459 two bridges for impl of java generic vararg method
A Scala method that implements a generic, Java-defined varargs method, needs two bridges: - to convert the collections for the repeated parameters (VBRIDGE) - to bridge the generics gap (BRIDGE) Refchecks emits the varargs bridges, and erasure takes care of the other gap. Because a VBRIDGE was also an ARTIFACT, it was wrongly considered inert with respect to erasure. No longer!
1 parent c2a448b commit 83b0826

File tree

5 files changed

+27
-1
lines changed

5 files changed

+27
-1
lines changed

src/compiler/scala/tools/nsc/transform/Erasure.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,13 @@ abstract class Erasure extends AddInterfaces
422422
val opc = enteringExplicitOuter {
423423
new overridingPairs.Cursor(root) {
424424
override def parents = List(root.info.firstParent)
425-
override def exclude(sym: Symbol) = !sym.isMethod || super.exclude(sym)
425+
// Varargs bridges may need generic bridges due to the non-repeated part of the signature of the involved methods.
426+
// The vararg bridge is generated during refchecks (probably to simplify override checking),
427+
// but then the resulting varargs "bridge" method is considered an artifact (why???),
428+
// causing `super.exclude` to veto it from our bridge generation here, unless we explicitly include it (hence `!sym.hasFlag(VBRIDGE) &&`).
429+
// TODO: could we generate just one bridge method that does both the java-vararg-array <-> scala-repeated-param-seq conversion
430+
// as well as the casts from the erased types of the overridden generic method (regular bridge method)?
431+
override def exclude(sym: Symbol) = !sym.isMethod || (!sym.hasFlag(VBRIDGE) && super.exclude(sym))
426432
}
427433
}
428434

test/files/run/t1459generic.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ab
2+
ab
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Impl extends VarargGeneric[String] {
2+
def genericOne(x: String, arg: String): String = x + arg
3+
def genericVar(x: String, args: String*): String = x + args.head
4+
}

test/files/run/t1459generic/Test.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
public class Test {
2+
public static void main(String[] args) throws Exception {
3+
VarargGeneric vg = new Impl();
4+
System.out.println(vg.genericOne("a", "b"));
5+
System.out.println(vg.genericVar("a", "b"));
6+
// should not result in java.lang.AbstractMethodError: Impl.genericVar(Ljava/lang/Object;[Ljava/lang/String;)Ljava/lang/String;
7+
// --> genericVar needs a varargs bridge (scala -> java varargs) and a standard generics bridge
8+
// (for comparison, including genericOne, which needs only a generics bridge)
9+
}
10+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public interface VarargGeneric<T> {
2+
String genericOne(T x, String args);
3+
String genericVar(T x, String... args);
4+
}

0 commit comments

Comments
 (0)
0