diff options
-rw-r--r-- | src/dotty/tools/dotc/Compiler.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/tpd.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Getters.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Memoize.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Mixin.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ResolveSuper.scala | 9 |
6 files changed, 24 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index 819b60d48..004a3868c 100644 --- a/src/dotty/tools/dotc/Compiler.scala +++ b/src/dotty/tools/dotc/Compiler.scala @@ -46,7 +46,6 @@ class Compiler { new TailRec), List(new PatternMatcher, new ExplicitOuter, - // new LazyValTranformContext().transformer, // disabled, awaiting fixes new Splitter), List(new ElimByName, new InterceptedMethods, @@ -55,7 +54,7 @@ class Compiler { new ResolveSuper), List(new Erasure), List(new Mixin, - new Memoize, + new Memoize, // TODO: Make LazyVals a part of this phase new CapturedVars, new Constructors), List(new LambdaLift, diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index 5aebbd6fe..735b218e3 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -546,10 +546,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { def traverse(tree: Tree) = tree match { case tree: DefTree => val sym = tree.symbol - if (sym.denot(ctx.withPhase(trans)).owner == from) { - println(i"change owner $from -> $to of $sym") + if (sym.denot(ctx.withPhase(trans)).owner == from) sym.copySymDenotation(owner = to).installAfter(trans) - } if (sym.isWeakOwner) traverseChildren(tree) case _ => traverseChildren(tree) diff --git a/src/dotty/tools/dotc/transform/Getters.scala b/src/dotty/tools/dotc/transform/Getters.scala index 55b70a790..4ea9d2c6b 100644 --- a/src/dotty/tools/dotc/transform/Getters.scala +++ b/src/dotty/tools/dotc/transform/Getters.scala @@ -36,6 +36,8 @@ import Decorators._ * * p.x = e * --> p.x_=(e) + * + * No fields are generated yet. This is done later in phase Memoize. */ class Getters extends MiniPhaseTransform with SymTransformer { thisTransform => import ast.tpd._ diff --git a/src/dotty/tools/dotc/transform/Memoize.scala b/src/dotty/tools/dotc/transform/Memoize.scala index 6b14d7714..ef70b9ecf 100644 --- a/src/dotty/tools/dotc/transform/Memoize.scala +++ b/src/dotty/tools/dotc/transform/Memoize.scala @@ -37,6 +37,12 @@ import Decorators._ override def phaseName = "memoize" override def treeTransformPhase = thisTransform.next + /** Should to run after mixin so that fields get generated in the + * class that contains the concrete getter rather than the trait + * that defines it. + */ + override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Mixin]) + override def prepareForDefDef(tree: DefDef)(implicit ctx: Context) = { val sym = tree.symbol if (sym.isGetter && !sym.is(NoFieldNeeded)) { diff --git a/src/dotty/tools/dotc/transform/Mixin.scala b/src/dotty/tools/dotc/transform/Mixin.scala index 668aca215..1d342404a 100644 --- a/src/dotty/tools/dotc/transform/Mixin.scala +++ b/src/dotty/tools/dotc/transform/Mixin.scala @@ -13,10 +13,10 @@ import Decorators._ import DenotTransformers._ import StdNames._ import NameOps._ +import Phases._ import ast.Trees._ import collection.mutable -// todo: interface /** This phase performs the following transformations: * * 1. (done in `traitDefs`) Map every concrete trait getter @@ -57,14 +57,20 @@ import collection.mutable * 3.3 (done in `setters`) For every concrete setter `<mods> def x_=(y: T)` in M: * * <mods> def x_=(y: T) = () + * + * Conceptually, this is the second half of the previous mixin phase. It needs to run + * after erasure because it copies references to possibly private inner classes and objects + * into enclosing classes where they are not visible. This can only be done if all references + * are symbolic. */ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform => import ast.tpd._ override def phaseName: String = "mixin" - override def treeTransformPhase = thisTransform.next + override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Erasure]) + override def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = if (sym.is(Accessor, butNot = Deferred) && sym.owner.is(Trait)) sym.copySymDenotation(initFlags = sym.flags | Deferred) diff --git a/src/dotty/tools/dotc/transform/ResolveSuper.scala b/src/dotty/tools/dotc/transform/ResolveSuper.scala index 1fd8b122f..23ff45a7c 100644 --- a/src/dotty/tools/dotc/transform/ResolveSuper.scala +++ b/src/dotty/tools/dotc/transform/ResolveSuper.scala @@ -39,6 +39,9 @@ import collection.mutable * * A method in M needs to be disambiguated if it is concrete, not overridden in C, * and if it overrides another concrete method. + * + * This is the first part of what was the mixin phase. It is complemented by + * Mixin, which runs after erasure. */ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform => import ast.tpd._ @@ -61,11 +64,11 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th var bcs = cls.info.baseClasses.dropWhile(acc.owner != _).tail var sym: Symbol = NoSymbol val SuperAccessorName(memberName) = acc.name: Name // dotty deviation: ": Name" needed otherwise pattern type is neither a subtype nor a supertype of selector type - println(i"starting rebindsuper from $cls of ${acc.showLocated}: ${acc.info} in $bcs, name = $memberName") + ctx.debuglog(i"starting rebindsuper from $cls of ${acc.showLocated}: ${acc.info} in $bcs, name = $memberName") while (bcs.nonEmpty && sym == NoSymbol) { val other = bcs.head.info.nonPrivateDecl(memberName) - //if (ctx.settings.debug.value) - println(i"rebindsuper ${bcs.head} $other deferred = ${other.symbol.is(Deferred)}") + if (ctx.settings.debug.value) + ctx.log(i"rebindsuper ${bcs.head} $other deferred = ${other.symbol.is(Deferred)}") sym = other.matchingDenotation(cls.thisType, cls.thisType.memberInfo(acc)).symbol bcs = bcs.tail } |