aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2016-12-17 18:39:10 +0100
committerGitHub <noreply@github.com>2016-12-17 18:39:10 +0100
commit9bbd04395f30748e57c0c93e768725adfac79769 (patch)
treea67cfea2c89c2dc7c6456aefde543935ea17bea6 /compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
parentd69e8490dc66f98719fa1483e57d824c3a61f99c (diff)
parenteb4795fb8893b88ffcf471849e3353531f2bc13e (diff)
downloaddotty-9bbd04395f30748e57c0c93e768725adfac79769.tar.gz
dotty-9bbd04395f30748e57c0c93e768725adfac79769.tar.bz2
dotty-9bbd04395f30748e57c0c93e768725adfac79769.zip
Merge pull request #1767 from dotty-staging/fix-#1755
Fix #1755: Make sure references in outer args are accessible
Diffstat (limited to 'compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala23
1 files changed, 21 insertions, 2 deletions
diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
index 4c5186712..5463d5080 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
@@ -95,7 +95,7 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
if (needsOuterIfReferenced(parentTrait)) {
val parentTp = cls.denot.thisType.baseTypeRef(parentTrait)
val outerAccImpl = newOuterAccessor(cls, parentTrait).enteredAfter(thisTransformer)
- newDefs += DefDef(outerAccImpl, singleton(outerPrefix(parentTp)))
+ newDefs += DefDef(outerAccImpl, singleton(fixThis(outerPrefix(parentTp))))
}
}
@@ -276,6 +276,25 @@ object ExplicitOuter {
outerPrefix(tpe.underlying)
}
+ /** It's possible (i1755.scala gives an example) that the type
+ * given by outerPrefix contains a This-reference to a module outside
+ * the context where that module is defined. This needs to be translated
+ * to an access to the module object from the enclosing class or object.
+ *
+ * This solution is a bit of a hack; it would be better to avoid
+ * such references to the This of a module from outside the module
+ * in the first place. I was not yet able to find out how such references
+ * arise and how to avoid them.
+ */
+ private def fixThis(tpe: Type)(implicit ctx: Context): Type = tpe match {
+ case tpe: ThisType if tpe.cls.is(Module) && !ctx.owner.isContainedIn(tpe.cls) =>
+ fixThis(TermRef(tpe.cls.owner.thisType, tpe.cls.sourceModule.asTerm))
+ case tpe: TermRef =>
+ tpe.derivedSelect(fixThis(tpe.prefix))
+ case _ =>
+ tpe
+ }
+
def outer(implicit ctx: Context): OuterOps = new OuterOps(ctx)
/** The operations in this class
@@ -314,7 +333,7 @@ object ExplicitOuter {
val cls = fun.symbol.owner.asClass
def outerArg(receiver: Tree): Tree = receiver match {
case New(_) | Super(_, _) =>
- singleton(outerPrefix(receiver.tpe))
+ singleton(fixThis(outerPrefix(receiver.tpe)))
case This(_) =>
ref(outerParamAccessor(cls)) // will be rewired to outer argument of secondary constructor in phase Constructors
case TypeApply(Select(r, nme.asInstanceOf_), args) =>