aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/transform
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
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')
-rw-r--r--compiler/src/dotty/tools/dotc/transform/MixinOps.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala51
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala16
3 files changed, 55 insertions, 15 deletions
diff --git a/compiler/src/dotty/tools/dotc/transform/MixinOps.scala b/compiler/src/dotty/tools/dotc/transform/MixinOps.scala
index c39e72b45..25aa9ffaf 100644
--- a/compiler/src/dotty/tools/dotc/transform/MixinOps.scala
+++ b/compiler/src/dotty/tools/dotc/transform/MixinOps.scala
@@ -68,7 +68,8 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx:
hasPrimitiveMissMatch(tp1.resultType, tp2.resultType) ||
tp1.paramTypess.flatten.zip(tp1.paramTypess.flatten).exists(args => hasPrimitiveMissMatch(args._1, args._2))
case _ =>
- tp1.typeSymbol.isPrimitiveValueClass ^ tp2.typeSymbol.isPrimitiveValueClass
+ def isPrimitiveOrValueClass(sym: Symbol): Boolean = sym.isPrimitiveValueClass || sym.isValueClass
+ isPrimitiveOrValueClass(tp1.typeSymbol) ^ isPrimitiveOrValueClass(tp2.typeSymbol)
}
def needsPrimitiveForwarder(m: Symbol): Boolean =
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)
+ }
+}
diff --git a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
index c4d8f5e33..3a301167d 100644
--- a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
@@ -38,14 +38,6 @@ import ResolveSuper._
*
* <mods> def f[Ts](ps1)...(psN): U = super[M].f[Ts](ps1)...(psN)
*
- * 3.3 (done in `methodPrimitiveForwarders`) 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)
- *
* A method in M needs to be disambiguated if it is concrete, not overridden in C,
* and if it overrides another concrete method.
*
@@ -73,11 +65,7 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
for (meth <- mixin.info.decls.toList if needsForwarder(meth))
yield polyDefDef(implementation(meth.asTerm), forwarder(meth))
- def methodPrimitiveForwarders: List[Tree] =
- for (meth <- mixins.flatMap(_.info.decls.flatMap(needsPrimitiveForwarderTo)).distinct)
- yield polyDefDef(implementation(meth.asTerm), forwarder(meth))
-
- val overrides = mixins.flatMap(mixin => superAccessors(mixin) ::: methodOverrides(mixin)) ::: methodPrimitiveForwarders
+ val overrides = mixins.flatMap(mixin => superAccessors(mixin) ::: methodOverrides(mixin))
cpy.Template(impl)(body = overrides ::: impl.body)
}
@@ -97,7 +85,7 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
private val PrivateOrAccessorOrDeferred = Private | Accessor | Deferred
}
-object ResolveSuper{
+object ResolveSuper {
/** Returns the symbol that is accessed by a super-accessor in a mixin composition.
*
* @param base The class in which everything is mixed together