@@ -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,24 @@ 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 = atPhase(erasurePhase) {
325+ cls.thisType.memberInfo(target)
310326 }
327+ if ! (infoBeforeErasure =:= sym.info) 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
311337
312338 cpy.Template (impl)(
313339 constr =
0 commit comments