8000 Merge pull request #5631 from adriaanm/ticket/9013 · scala/scala@6644017 · GitHub
[go: up one dir, main page]

8000 Skip to content

Commit 6644017

Browse files
authored
Merge pull request #5631 from adriaanm/ticket/9013
SI-9013 SI-1459 Inherit @VarArgs annotations
2 parents 90a764b + a75d3fd commit 6644017

File tree

15 files changed

+121
-19
lines changed

15 files changed

+121
-19
lines changed

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

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -411,20 +411,23 @@ abstract class Erasure extends AddInterfaces
411411
override def newTyper(context: Context) = new Eraser(context)
412412

413413
class ComputeBridges(unit: CompilationUnit, root: Symbol) {
414-
assert(phase == currentRun.erasurePhase, phase)
414+
415+
class BridgesCursor(root: Symbol) extends overridingPairs.Cursor(root) {
416+
override def parents = List(root.info.firstParent)
417+
// Varargs bridges may need generic bridges due to the non-repeated part of the signature of the involved methods.
418+
// The vararg bridge is generated during refchecks (probably to simplify override checking),
419+
// but then the resulting varargs "bridge" method may itself need an actual erasure bridge.
420+
// TODO: like javac, generate just one bridge method that wraps Seq <-> varargs and does erasure-induced casts
421+
override def exclude(sym: Symbol) = !sym.isMethod || super.exclude(sym)
422+
}
415423

416424
var toBeRemoved = immutable.Set[Symbol]()
417425
val site = root.thisType
418426
val bridgesScope = newScope
419427
val bridgeTarget = mutable.HashMap[Symbol, Symbol]()
420428
var bridges = List[Tree]()
421429

422-
val opc = enteringExplicitOuter {
423-
new overridingPairs.Cursor(root) {
424-
override def parents = List(root.info.firstParent)
425-
override def exclude(sym: Symbol) = !sym.isMethod || super.exclude(sym)
426-
}
427-
}
430+
val opc = enteringExplicitOuter { new BridgesCursor(root) }
428431

429432
def compute(): (List[Tree], immutable.Set[Symbol]) = {
430433
while (opc.hasNext) {
@@ -811,6 +814,16 @@ abstract class Erasure extends AddInterfaces
811814
}
812815
}
813816

817+
private class DoubleDefsCursor(root: Symbol) extends Cursor(root) {
818+
// specialized members have no type history before 'specialize', causing double def errors for curried defs
819+
override def exclude(sym: Symbol): Boolean = (
820+
sym.isType
821+
|| super.exclude(sym)
822+
|| !sym.hasTypeAt(currentRun.refchecksPhase.id)
823+
)
824+
override def matches(lo: Symbol, high: Symbol) = !high.isPrivate
825+
}
826+
814827
/** Emit an error if there is a double definition. This can happen if:
815828
*
816829
* - A template defines two members with the same name and erased type.
@@ -821,21 +834,12 @@ abstract class Erasure extends AddInterfaces
821834
*/
822835
private def checkNoDoubleDefs(root: Symbol) {
823836
checkNoDeclaredDoubleDefs(root)
824-
object opc extends Cursor(root) {
825-
// specialized members have no type history before 'specialize', causing double def errors for curried defs
826-
override def exclude(sym: Symbol): Boolean = (
827-
sym.isType
828-
|| super.exclude(sym)
829-
|| !sym.hasTypeAt(currentRun.refchecksPhase.id)
830-
)
831-
override def matches(lo: Symbol, high: Symbol) = !high.isPrivate
832-
}
833837
def isErasureDoubleDef(pair: SymbolPair) = {
834838
import pair._
835839
log(s"Considering for erasure clash:\n$pair")
836840
!exitingRefchecks(lowType matches highType) && sameTypeAfterErasure(low, high)
837841
}
838-
opc.iterator filter isErasureDoubleDef foreach doubleDefError
842+
(new DoubleDefsCursor(root)).iterator filter isErasureDoubleDef foreach doubleDefError
839843
}
840844

841845
/** Add bridge definitions to a template. This means:

src/compiler/scala/tools/nsc/typechecker/RefChecks.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
193193
def varargBridge(member: Symbol, bridgetpe: Type): Tree = {
194194
log(s"Generating varargs bridge for ${member.fullLocationString} of type $bridgetpe")
195195

196-
val newFlags = (member.flags | VBRIDGE | ARTIFACT) & ~PRIVATE
196+
val newFlags = (member.flags | VBRIDGE) & ~PRIVATE
197197
val bridge = member.cloneSymbolImpl(clazz, newFlags) setPos clazz.pos
198198
bridge.setInfo(bridgetpe.cloneInfo(bridge))
199199
clazz.info.decls enter bridge

src/reflect/scala/reflect/internal/Flags.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ class Flags extends ModifierFlags {
164164

165165
final val LOCKED = 1L << 39 // temporary flag to catch cyclic dependencies
166166
final val SPECIALIZED = 1L << 40 // symbol is a generated specialized member
167-
final val VBRIDGE = 1L << 42 // symbol is a varargs bridge
167+
final val VBRIDGE = 1L << 42 // symbol is a varargs bridge (but not a bridge at the bytecode level)
168168

169169
final val VARARGS = 1L << 43 // symbol is a Java-style varargs method
170170
final val TRIEDCOOKING = 1L << 44 // `Cooking` has been tried on this symbol

test/files/run/t1459.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
JavaPrinter: one two three
2+
InheritingPrinter extends JavaPrinter: one two three
3+
ScalaPrinter: onetwothree
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class InheritingPrinter extends JavaPrinter {
2+
override def doit(s: String*) {
3+
print("InheritingPrinter extends ")
4+
super.doit(s: _*);
5+
}
6+
}

test/files/run/t1459/JavaPrinter.java

Lines changed: 7 additions & 0 deletions
+
for(String str : s)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public class JavaPrinter implements VarArg {
2+
public void doit(String... s) {
3+
System.out.print("JavaPrinter: ");
4
5+
System.out.print(str + " ");
6+
}
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class ScalaPrinter extends VarArg {
2+
override def doit(s: String*) = {
3+
print("ScalaPrinter: ")
4+
s.foreach(print _)
5+
}
6+
}

test/files/run/t1459/Test.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
public class Test {
2+
public static void main(String[] args) {
3+
VarArg jp = new JavaPrinter();
4+
VarArg ip = new InheritingPrinter();
5+
VarArg sp = new ScalaPrinter();
6+
doYourThing(jp);
7+
doYourThing(ip);
8+
doYourThing(sp);
9+
}
10+
11+
public static void doYourThing(VarArg va) {
12+
va.doit("one", "two", "three");
13+
System.out.println();
14+
}
15+
}

test/files/run/t1459/VarArg.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public interface VarArg {
2+
void doit(String... s);
3+
}

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

0 commit comments

Comments
 (0)
0