@@ -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
@@ -305,8 +315,25 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
305
315
for (meth <- mixin.info.decls.toList if needsMixinForwarder(meth))
306
316
yield {
307
317
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))
309
326
}
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
310
337
311
338
cpy.Template (impl)(
312
339
constr =
0 commit comments