Skip to content

Commit 8130c32

Browse files
committed
Handle overloaded members when generating Java varargs bridges
Fixes #13043
1 parent cf6fa97 commit 8130c32

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
package dotty.tools.dotc
1+
package dotty.tools
2+
package dotc
23
package transform
34

45
import core._
@@ -76,7 +77,23 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
7677

7778
override def infoMayChange(sym: Symbol)(using Context): Boolean = sym.is(Method)
7879

79-
private def overridesJava(sym: Symbol)(using Context) = sym.allOverriddenSymbols.exists(_.is(JavaDefined))
80+
/** Does `sym` override a symbol defined in a Java class? One might think that
81+
* this can be expressed as
82+
*
83+
* sym.allOverriddenSymbols.exists(_.is(JavaDefined))
84+
*
85+
* but that does not work, since `allOverriddenSymbols` gets confused because the
86+
* signatures of a Java varargs method and a Scala varargs override are not the same.
87+
*/
88+
private def overridesJava(sym: Symbol)(using Context) =
89+
sym.owner.info.baseClasses.drop(1).exists { bc =>
90+
bc.is(JavaDefined) && {
91+
val other = bc.info.nonPrivateDecl(sym.name)
92+
other.hasAltWith { alt =>
93+
sym.owner.thisType.memberInfo(alt.symbol).matchesLoosely(sym.info)
94+
}
95+
}
96+
}
8097

8198
private def hasVarargsAnnotation(sym: Symbol)(using Context) = sym.hasAnnotation(defn.VarargsAnnot)
8299

@@ -85,7 +102,8 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
85102
private def isVarargsMethod(sym: Symbol)(using Context) =
86103
hasVarargsAnnotation(sym) ||
87104
hasRepeatedParams(sym) &&
88-
(sym.allOverriddenSymbols.exists(s => s.is(JavaDefined) || hasVarargsAnnotation(s)))
105+
overridesJava(sym)
106+
|| sym.allOverriddenSymbols.exists(hasVarargsAnnotation)
89107

90108
/** Eliminate repeated parameters from method types. */
91109
private def elimRepeated(tp: Type, isJava: Boolean)(using Context): Type = tp.stripTypeVar match
@@ -292,6 +310,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
292310
report.error(s"$src produces a forwarder method that conflicts with ${conflict.showDcl}", original.srcPos)
293311
case Nil =>
294312
forwarder.enteredAfter(thisPhase)
313+
end addVarArgsForwarder
295314

296315
/** Convert type from Scala to Java varargs method */
297316
private def toJavaVarArgs(tp: Type)(using Context): Type = tp match

tests/pos/i13043/Impl.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class Impl extends Intf {
2+
override def thing(x: Int) = ???
3+
override def thing(y: String*) = ???
4+
override def thing2(y: String*) = ???
5+
}

tests/pos/i13043/Intf.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
interface Intf {
2+
public void thing(int x);
3+
public void thing(String... y);
4+
public void thing2(String... y);
5+
}

0 commit comments

Comments
 (0)