aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Petrashko <dark@d-d.me>2015-09-18 13:11:20 +0100
committerDmitry Petrashko <dark@d-d.me>2015-09-18 13:11:20 +0100
commitec683c17773ab86782859fdc678d98c34810c1f3 (patch)
tree5b9d8ccbe7a85bd925a518979a6c8e68f8dfe5cf
parent62e136a3301ed873783b51261c943bd3d6d7267d (diff)
parent50e3a7d92f4b7cc4cd922eb92c7ed8bf793b159c (diff)
downloaddotty-ec683c17773ab86782859fdc678d98c34810c1f3.tar.gz
dotty-ec683c17773ab86782859fdc678d98c34810c1f3.tar.bz2
dotty-ec683c17773ab86782859fdc678d98c34810c1f3.zip
Merge pull request #796 from dotty-staging/fix-#789-problems-in-erasure
Fix #789 problems in erasure
-rw-r--r--src/dotty/tools/dotc/Compiler.scala1
-rw-r--r--src/dotty/tools/dotc/core/Types.scala5
-rw-r--r--src/dotty/tools/dotc/transform/ExplicitSelf.scala37
-rw-r--r--tests/run/i789.check1
-rw-r--r--tests/run/i789.scala20
5 files changed, 63 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index c537d8885..a36743b59 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -52,6 +52,7 @@ class Compiler {
new ClassOf),
List(new PatternMatcher,
new ExplicitOuter,
+ new ExplicitSelf,
new Splitter),
List(new VCInlineMethods,
new SeqLiterals,
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index d04da30c0..358720836 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2530,7 +2530,7 @@ object Types {
def selfType(implicit ctx: Context): Type = {
if (selfTypeCache == null)
selfTypeCache = {
- def fullRef = fullyAppliedRef(cls.typeRef, cls.typeParams)
+ def fullRef = fullyAppliedRef
val given = givenSelfType
val raw =
if (!given.exists) fullRef
@@ -2561,6 +2561,9 @@ object Types {
base
}
+ /** The class type with all type parameters */
+ def fullyAppliedRef(implicit ctx: Context): Type = fullyAppliedRef(cls.typeRef, cls.typeParams)
+
def rebase(tp: Type)(implicit ctx: Context): Type =
if ((prefix eq cls.owner.thisType) || !cls.owner.isClass || ctx.erasedTypes) tp
else tp.substThis(cls.owner.asClass, prefix)
diff --git a/src/dotty/tools/dotc/transform/ExplicitSelf.scala b/src/dotty/tools/dotc/transform/ExplicitSelf.scala
new file mode 100644
index 000000000..c6a218157
--- /dev/null
+++ b/src/dotty/tools/dotc/transform/ExplicitSelf.scala
@@ -0,0 +1,37 @@
+package dotty.tools.dotc
+package transform
+
+import core._
+import Contexts.Context
+import Types._
+import TreeTransforms._
+import Decorators._
+import ast.Trees._
+import Flags._
+
+/** Transform references of the form
+ *
+ * C.this.m
+ *
+ * where `C` is a class with explicit self type and `C` is not a
+ * subclass of the owner of `m` to
+ *
+ * C.this.asInstanceOf[S].m
+ *
+ * where `S` is the self type of `C`.
+ */
+class ExplicitSelf extends MiniPhaseTransform { thisTransform =>
+ import ast.tpd._
+
+ override def phaseName = "explicitSelf"
+
+ override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
+ case Select(thiz: This, name) if name.isTermName =>
+ val cls = thiz.symbol.asClass
+ val cinfo = cls.classInfo
+ if (cinfo.givenSelfType.exists && !cls.derivesFrom(tree.symbol.owner))
+ cpy.Select(tree)(thiz.asInstance(cinfo.selfType), name)
+ else tree
+ case _ => tree
+ }
+}
diff --git a/tests/run/i789.check b/tests/run/i789.check
new file mode 100644
index 000000000..d41f69423
--- /dev/null
+++ b/tests/run/i789.check
@@ -0,0 +1 @@
+atPhase: 2
diff --git a/tests/run/i789.scala b/tests/run/i789.scala
new file mode 100644
index 000000000..99b081f0a
--- /dev/null
+++ b/tests/run/i789.scala
@@ -0,0 +1,20 @@
+ trait Periods { self: Context =>
+
+ def atPhase(id: Int): Unit = println(s"atPhase: $id")
+
+ }
+
+ class Phase(val id: Int)
+
+ trait Phases { self: Context =>
+ def atPhase(phase: Phase): Unit = self.atPhase(phase.id)
+ }
+
+ trait Context extends Phases with Periods
+
+ object Test extends Context {
+
+ def main(args: Array[String]) = atPhase(new Phase(2))
+
+ }
+