
dotty.tools.dotc.transform.PrimitiveForwarders.scala Maven / Gradle / Ivy
package dotty.tools.dotc
package transform
import core._
import MegaPhase._
import Contexts.Context
import Flags._
import SymUtils._
import Symbols._
import SymDenotations._
import Types._
import Decorators._
import DenotTransformers._
import StdNames._
import NameOps._
import ast.Trees._
import util.Positions._
import Names._
import collection.mutable
import ResolveSuper._
/** This phase adds forwarder where mixedin generic and primitive typed methods have a missmatch.
* In particular for every method that is declared both as generic with a primitive type and with a primitive type
* ` def f[Ts](ps1)...(psN): U` in trait M` and
* ` def f[Ts](ps1)...(psN): V = ...` in implemented in N`
* where U is a primitive and V a polymorphic type (or vice versa) needs:
*
* def f[Ts](ps1)...(psN): U = super[N].f[Ts](ps1)...(psN)
*
* IMPORTANT: When\If Valhalla happens, we'll need to move mixin before erasure and than this code will need to be rewritten
* as it will instead change super-class.
*/
class PrimitiveForwarders extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
override def phaseName: String = "primitiveForwarders"
override def runsAfter = Set(ResolveSuper.name)
override def changesMembers = true // the phase adds primitive forwarders
override def transformTemplate(impl: Template)(implicit ctx: Context) = {
val cls = impl.symbol.owner.asClass
val ops = new MixinOps(cls, thisPhase)
import ops._
def methodPrimitiveForwarders: List[Tree] =
for (meth <- mixins.flatMap(_.info.decls.toList.flatMap(needsPrimitiveForwarderTo)).distinct)
yield polyDefDef(implementation(meth.asTerm), forwarder(meth))
cpy.Template(impl)(body = methodPrimitiveForwarders ::: impl.body)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy