Skip to content

Commit eb4795f

Browse files
committed
Fix #1755: Make sure references in outer args are accessible
Needed a fixup action in ExplicitOuter to avoid references to module's This from outside their scope. The problem is fixed, but I wish I understood better the root cause.
1 parent 47d2084 commit eb4795f

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

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

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

280299
/** The operations in this class
@@ -313,7 +332,7 @@ object ExplicitOuter {
313332
val cls = fun.symbol.owner.asClass
314333
def outerArg(receiver: Tree): Tree = receiver match {
315334
case New(_) | Super(_, _) =>
316-
singleton(outerPrefix(receiver.tpe))
335+
singleton(fixThis(outerPrefix(receiver.tpe)))
317336
case This(_) =>
318337
ref(outerParamAccessor(cls)) // will be rewired to outer argument of secondary constructor in phase Constructors
319338
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)