diff options
author | Martin Odersky <odersky@gmail.com> | 2016-09-05 11:51:14 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-10-02 16:11:21 +0200 |
commit | 1d932642eaed2ec9829be951f3272d32b4393a39 (patch) | |
tree | 6e7263cc14896b604d0522f01c73644f6d54ea54 /src/dotty/tools/dotc/transform | |
parent | 0bd955e7780c95d41a0b6c4b7ca221f00e3cfd92 (diff) | |
download | dotty-1d932642eaed2ec9829be951f3272d32b4393a39.tar.gz dotty-1d932642eaed2ec9829be951f3272d32b4393a39.tar.bz2 dotty-1d932642eaed2ec9829be951f3272d32b4393a39.zip |
Handle outer this in Inliner
Also, do some refactorings and fix some bugs in Inliner.
Diffstat (limited to 'src/dotty/tools/dotc/transform')
4 files changed, 10 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 60ef1b306..3f235dca7 100644 --- a/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -57,6 +57,12 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf override def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym.isClass + /** Convert a selection of the form `qual.C_<OUTER>` to an outer path from `qual` to `C` */ + override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) = + if (tree.name.isOuterSelect) + outer.path(tree.tpe.widen.classSymbol, tree.qualifier).ensureConforms(tree.tpe) + else tree + /** First, add outer accessors if a class does not have them yet and it references an outer this. * If the class has outer accessors, implement them. * Furthermore, if a parent trait might have an outer accessor, diff --git a/src/dotty/tools/dotc/transform/FirstTransform.scala b/src/dotty/tools/dotc/transform/FirstTransform.scala index 6e1fed607..74dc9b9d6 100644 --- a/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -72,8 +72,8 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = { tree match { - case Select(qual, _) if tree.symbol.exists => - assert(qual.tpe derivesFrom tree.symbol.owner, i"non member selection of ${tree.symbol.showLocated} from ${qual.tpe}") + case Select(qual, name) if !name.isOuterSelect && tree.symbol.exists => + assert(qual.tpe derivesFrom tree.symbol.owner, i"non member selection of ${tree.symbol.showLocated} from ${qual.tpe} in $tree") case _: TypeTree => case _: Import | _: NamedArg | _: TypTree => assert(false, i"illegal tree: $tree") diff --git a/src/dotty/tools/dotc/transform/PatternMatcher.scala b/src/dotty/tools/dotc/transform/PatternMatcher.scala index 490feb7d0..49c0eabec 100644 --- a/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -782,6 +782,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer { val expectedClass = expectedTp.dealias.classSymbol.asClass val test = codegen._asInstanceOf(testedBinder, expectedTp) + // TODO: Use nme.OUTER_SELECT, like the Inliner does? val outerAccessorTested = ctx.atPhase(ctx.explicitOuterPhase.next) { implicit ctx => ExplicitOuter.ensureOuterAccessors(expectedClass) test.select(ExplicitOuter.outerAccessor(expectedClass)).select(defn.Object_eq).appliedTo(expectedOuter) diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala index 6af991f27..10be6db65 100644 --- a/src/dotty/tools/dotc/transform/SuperAccessors.scala +++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala @@ -148,7 +148,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) { */ private def ensureProtectedAccessOK(sel: Select, targs: List[Tree])(implicit ctx: Context) = { val sym = sel.symbol - if (sym.exists && needsProtectedAccessor(sym, sel.pos)) { + if (sym.isTerm && !sel.name.isOuterSelect && needsProtectedAccessor(sym, sel.pos)) { ctx.debuglog("Adding protected accessor for " + sel) protectedAccessorCall(sel, targs) } else sel |