aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
diff options
context:
space:
mode:
authorNicolas Stucki <nicolas.stucki@gmail.com>2017-01-11 18:41:58 +0100
committerNicolas Stucki <nicolas.stucki@gmail.com>2017-01-11 18:41:58 +0100
commitcf57534c6141593fbe2ac2fec9d101fa662ecf05 (patch)
tree440cddbb105cf313032ff9b6d1d433f379e098a8 /compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
parent9f505a42a1c100eedab9748321a77d4bc345af61 (diff)
downloaddotty-cf57534c6141593fbe2ac2fec9d101fa662ecf05.tar.gz
dotty-cf57534c6141593fbe2ac2fec9d101fa662ecf05.tar.bz2
dotty-cf57534c6141593fbe2ac2fec9d101fa662ecf05.zip
Add PrimitiveForwarders and fix forwarding on value classes.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala51
1 files changed, 51 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala b/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
new file mode 100644
index 000000000..d752ce8e7
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
@@ -0,0 +1,51 @@
+package dotty.tools.dotc
+package transform
+
+import core._
+import TreeTransforms._
+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
+ * `<mods> def f[Ts](ps1)...(psN): U` in trait M` and
+ * `<mods> def f[Ts](ps1)...(psN): V = ...` in implemented in N`
+ * where U is a primitive and V a polymorphic type (or vice versa) needs:
+ *
+ * <mods> 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 MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+ import ast.tpd._
+
+ override def phaseName: String = "primitiveForwarders"
+
+ override def runsAfter = Set(classOf[ResolveSuper])
+
+ override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo) = {
+ val cls = impl.symbol.owner.asClass
+ val ops = new MixinOps(cls, thisTransform)
+ import ops._
+
+ def methodPrimitiveForwarders: List[Tree] =
+ for (meth <- mixins.flatMap(_.info.decls.flatMap(needsPrimitiveForwarderTo)).distinct)
+ yield polyDefDef(implementation(meth.asTerm), forwarder(meth))
+
+ cpy.Template(impl)(body = methodPrimitiveForwarders ::: impl.body)
+ }
+}