@@ -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