Skip to content

Commit a886727

Browse files
authored
Merge pull request #2076 from dotty-staging/fix/override-java-varargs
Fix overriding a Java method with varargs
2 parents d1f2ef4 + 568b1e7 commit a886727

File tree

5 files changed

+30
-6
lines changed

5 files changed

+30
-6
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ class Compiler {
4848
List(new Pickler), // Generate TASTY info
4949
List(new FirstTransform, // Some transformations to put trees into a canonical form
5050
new CheckReentrant), // Internal use only: Check that compiled program has no data races involving global vars
51-
List(new RefChecks, // Various checks mostly related to abstract members and overriding
52-
new CheckStatic, // Check restrictions that apply to @static members
51+
List(new CheckStatic, // Check restrictions that apply to @static members
5352
new ElimRepeated, // Rewrite vararg parameters and arguments
53+
new RefChecks, // Various checks mostly related to abstract members and overriding
5454
new NormalizeFlags, // Rewrite some definition flags
5555
new ExtensionMethods, // Expand methods of value classes with extension methods
5656
new ExpandSAMs, // Expand single abstract method closures to anonymous classes

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,21 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
3232
def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type =
3333
elimRepeated(tp)
3434

35+
36+
override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation =
37+
super.transform(ref) match {
38+
case ref1: SymDenotation if (ref1 ne ref) && overridesJava(ref1.symbol) =>
39+
// This method won't override the corresponding Java method at the end of this phase,
40+
// only the bridge added by `addVarArgsBridge` will.
41+
ref1.copySymDenotation(initFlags = ref1.flags &~ Override)
42+
case ref1 =>
43+
ref1
44+
}
45+
3546
override def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym is Method
3647

48+
private def overridesJava(sym: Symbol)(implicit ctx: Context) = sym.allOverriddenSymbols.exists(_ is JavaDefined)
49+
3750
private def elimRepeated(tp: Type)(implicit ctx: Context): Type = tp.stripTypeVar match {
3851
case tp @ MethodType(paramNames, paramTypes) =>
3952
val resultType1 = elimRepeated(tp.resultType)
@@ -93,10 +106,9 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
93106
*/
94107
override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
95108
assert(ctx.phase == thisTransformer)
96-
def overridesJava = tree.symbol.allOverriddenSymbols.exists(_ is JavaDefined)
97-
if (tree.symbol.info.isVarArgsMethod && overridesJava)
98-
addVarArgsBridge(tree)(ctx.withPhase(thisTransformer.next))
99-
else
109+
if (tree.symbol.info.isVarArgsMethod && overridesJava(tree.symbol))
110+
addVarArgsBridge(tree)
111+
else
100112
tree
101113
}
102114

@@ -120,6 +132,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
120132
.appliedToArgs(vrefs :+ TreeGen.wrapArray(varArgRef, elemtp))
121133
.appliedToArgss(vrefss1)
122134
})
135+
123136
Thicket(ddef, bridgeDef)
124137
}
125138

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,9 @@ class RefChecks extends MiniPhase { thisTransformer =>
766766

767767
override def phaseName: String = "refchecks"
768768

769+
// Needs to run after ElimRepeated for override checks involving varargs methods
770+
override def runsAfter = Set(classOf[ElimRepeated])
771+
769772
val treeTransform = new Transform(NoLevelInfo)
770773

771774
class Transform(currentLevel: RefChecks.OptLevelInfo = RefChecks.NoLevelInfo) extends TreeTransform {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class Base {
2+
public Object foo(Object... x) {
3+
return x;
4+
}
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Sub extends Base {
2+
override def foo(x: Object*): Object = x
3+
}

0 commit comments

Comments
 (0)