@@ -16,6 +16,7 @@ import StdNames.*
16
16
import Names .*
17
17
import NameKinds .*
18
18
import NameOps .*
19
+ import Phases .erasurePhase
19
20
import ast .Trees .*
20
21
21
22
import dotty .tools .dotc .transform .sjs .JSSymUtils .isJSType
@@ -115,6 +116,15 @@ object Mixin {
115
116
class Mixin extends MiniPhase with SymTransformer { thisPhase =>
116
117
import ast .tpd .*
117
118
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
+
118
128
override def phaseName : String = Mixin .name
119
129
120
130
override def description : String = Mixin .description
@@ -306,8 +316,24 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
306
316
for (meth <- mixin.info.decls.toList if needsMixinForwarder(meth))
307
317
yield {
308
318
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)
310
326
}
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
311
337
312
338
cpy.Template (impl)(
313
339
constr =
0 commit comments