Skip to content

Commit 9bbd043

Browse files
authored
Merge pull request #1767 from dotty-staging/fix-#1755
Fix #1755: Make sure references in outer args are accessible
2 parents d69e849 + eb4795f commit 9bbd043

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
9595
if (needsOuterIfReferenced(parentTrait)) {
9696
val parentTp = cls.denot.thisType.baseTypeRef(parentTrait)
9797
val outerAccImpl = newOuterAccessor(cls, parentTrait).enteredAfter(thisTransformer)
98-
newDefs += DefDef(outerAccImpl, singleton(outerPrefix(parentTp)))
98+
newDefs += DefDef(outerAccImpl, singleton(fixThis(outerPrefix(parentTp))))
9999
}
100100
}
101101

@@ -276,6 +276,25 @@ object ExplicitOuter {
276276
outerPrefix(tpe.underlying)
277277
}
278278

279+
/** It's possible (i1755.scala gives an example) that the type
280+
* given by outerPrefix contains a This-reference to a module outside
281+
* the context where that module is defined. This needs to be translated
282+
* to an access to the module object from the enclosing class or object.
283+
*
284+
* This solution is a bit of a hack; it would be better to avoid
285+
* such references to the This of a module from outside the module
286+
* in the first place. I was not yet able to find out how such references
287+
* arise and how to avoid them.
288+
*/
289+
private def fixThis(tpe: Type)(implicit ctx: Context): Type = tpe match {
290+
case tpe: ThisType if tpe.cls.is(Module) && !ctx.owner.isContainedIn(tpe.cls) =>
291+
fixThis(TermRef(tpe.cls.owner.thisType, tpe.cls.sourceModule.asTerm))
292+
case tpe: TermRef =>
293+
tpe.derivedSelect(fixThis(tpe.prefix))
294+
case _ =>
295+
tpe
296+
}
297+
279298
def outer(implicit ctx: Context): OuterOps = new OuterOps(ctx)
280299

281300
/** The operations in this class
@@ -314,7 +333,7 @@ object ExplicitOuter {
314333
val cls = fun.symbol.owner.asClass
315334
def outerArg(receiver: Tree): Tree = receiver match {
316335
case New(_) | Super(_, _) =>
317-
singleton(outerPrefix(receiver.tpe))
336+
singleton(fixThis(outerPrefix(receiver.tpe)))
318337
case This(_) =>
319338
ref(outerParamAccessor(cls)) // will be rewired to outer argument of secondary constructor in phase Constructors
320339
case TypeApply(Select(r, nme.asInstanceOf_), args) =>

tests/pos/i1755.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class hierarOverload {
2+
trait AB {
3+
type TB
4+
protected trait A { val entities: List[TB] }
5+
protected trait B
6+
}
7+
object NAnB {
8+
type TB = nB
9+
type TA = nA
10+
class nA { List[nB]() }
11+
class nB {}
12+
}
13+
def foo = { val t = new NAnB.TB() }
14+
}
15+
class hierarOverload2 {
16+
object NAnB {
17+
type TB = nB
18+
class nB
19+
}
20+
def foo = { val t = new NAnB.TB() }
21+
}

0 commit comments

Comments
 (0)