@@ -16,6 +16,7 @@ import StdNames.*
1616import Names.*
1717import NameKinds.*
1818import NameOps.*
19+ import Phases.erasurePhase
1920import ast.Trees.*
2021
2122import dotty.tools.dotc.transform.sjs.JSSymUtils.isJSType
@@ -115,6 +116,15 @@ object Mixin {
115116class Mixin extends MiniPhase with SymTransformer { thisPhase =>
116117 import ast.tpd.*
117118
119+ /** Infos before erasure of the generated mixin forwarders.
120+ *
121+ * These will be used to generate Java generic signatures of the mixin
122+ * forwarders. Normally we use the types before erasure; we cannot do that
123+ * for mixin forwarders since they are created after erasure, and therefore
124+ * their type history does not have anything recorded for before erasure.
125+ */
126+ val mixinForwarderGenericInfos = MutableSymbolMap[Type]()
127+
118128 override def phaseName: String = Mixin.name
119129
120130 override def description: String = Mixin.description
@@ -305,8 +315,25 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
305315 for (meth <- mixin.info.decls.toList if needsMixinForwarder(meth))
306316 yield {
307317 util.Stats.record("mixin forwarders")
308- transformFollowing(DefDef(mkForwarderSym(meth.asTerm, extraFlags = MixedIn), forwarderRhsFn(meth)))
318+ transformFollowing(DefDef(mkMixinForwarderSym(meth.asTerm), forwarderRhsFn(meth)))
319+ }
320+
321+ def mkMixinForwarderSym(target: TermSymbol): TermSymbol =
322+ val sym = mkForwarderSym(target, extraFlags = MixedIn)
323+ val (infoBeforeErasure, isDifferentThanInfoNow) = atPhase(erasurePhase) {
324+ val beforeErasure = cls.thisType.memberInfo(target)
325+ (beforeErasure, !(beforeErasure =:= sym.info))
309326 }
327+ if isDifferentThanInfoNow then
328+ // The info before erasure would not have been the same as the info now.
329+ // We want to store it for the backend to compute the generic Java signature.
330+ // However, we must still avoid doing that if erasing that signature would
331+ // not give the same erased type. If it doesn't, we'll just give a completely
332+ // incorrect Java signature. (This could be improved by generating dedicated
333+ // bridges, but we don't go that far; scalac doesn't either.)
334+ if TypeErasure.transformInfo(target, infoBeforeErasure) =:= sym.info then
335+ mixinForwarderGenericInfos(sym) = infoBeforeErasure
336+ sym
310337
311338 cpy.Template(impl)(
312339 constr =
0 commit comments