@@ -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
@@ -306,8 +316,25 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
306316 for (meth <- mixin.info.decls.toList if needsMixinForwarder(meth))
307317 yield {
308318 util.Stats .record(" mixin forwarders" )
309- transformFollowing(DefDef (mkForwarderSym(meth.asTerm, extraFlags = MixedIn ), forwarderRhsFn(meth)))
319+ transformFollowing(DefDef (mkMixinForwarderSym(meth.asTerm), forwarderRhsFn(meth)))
320+ }
321+
322+ def mkMixinForwarderSym (target : TermSymbol ): TermSymbol =
323+ val sym = mkForwarderSym(target, extraFlags = MixedIn )
324+ val (infoBeforeErasure, isDifferentThanInfoNow) = atPhase(erasurePhase) {
325+ val beforeErasure = cls.thisType.memberInfo(target)
326+ (beforeErasure, ! (beforeErasure =:= sym.info))
310327 }
328+ if isDifferentThanInfoNow then
329+ // The info before erasure would not have been the same as the info now.
330+ // We want to store it for the backend to compute the generic Java signature.
331+ // However, we must still avoid doing that if erasing that signature would
332+ // not give the same erased type. If it doesn't, we'll just give a completely
333+ // incorrect Java signature. (This could be improved by generating dedicated
334+ // bridges, but we don't go that far; scalac doesn't either.)
335+ if TypeErasure .transformInfo(target, infoBeforeErasure) =:= sym.info then
336+ mixinForwarderGenericInfos(sym) = infoBeforeErasure
337+ sym
311338
312339 cpy.Template (impl)(
313340 constr =
0 commit comments