diff options
author | Dmitry Petrashko <dark@d-d.me> | 2015-09-18 13:11:20 +0100 |
---|---|---|
committer | Dmitry Petrashko <dark@d-d.me> | 2015-09-18 13:11:20 +0100 |
commit | ec683c17773ab86782859fdc678d98c34810c1f3 (patch) | |
tree | 5b9d8ccbe7a85bd925a518979a6c8e68f8dfe5cf | |
parent | 62e136a3301ed873783b51261c943bd3d6d7267d (diff) | |
parent | 50e3a7d92f4b7cc4cd922eb92c7ed8bf793b159c (diff) | |
download | dotty-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.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ExplicitSelf.scala | 37 | ||||
-rw-r--r-- | tests/run/i789.check | 1 | ||||
-rw-r--r-- | tests/run/i789.scala | 20 |
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)) + + } + |