From c40302cf0b0545cfe023fd5f8c833114398f8ff7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 3 Jan 2017 19:12:18 +0700 Subject: [PATCH 1/2] Fix #1865: Compute outer path at right phase When computing the outer path, we need to be careful to dealias before erasure, even if the outer path is demanded during erasure. Otherwise we lose prefixes. --- .../tools/dotc/transform/ExplicitOuter.scala | 3 ++- tests/pending/pos/i1865.scala | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/pending/pos/i1865.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 1eb12e9dea77..497b73807ab8 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -276,7 +276,7 @@ object ExplicitOuter { if (tpe.prefix eq NoPrefix) cls.owner.enclosingClass.thisType else tpe.prefix case _ => - outerPrefix(tpe.underlying) + outerPrefix(tpe.underlying(ctx.withPhaseNoLater(ctx.erasurePhase))) } case tpe: TypeProxy => outerPrefix(tpe.underlying) @@ -339,6 +339,7 @@ object ExplicitOuter { val cls = fun.symbol.owner.asClass def outerArg(receiver: Tree): Tree = receiver match { case New(_) | Super(_, _) => + println(i"outerarg: ${receiver.tpe} --> ${outerPrefix(receiver.tpe)} at ${ctx.phase}") singleton(fixThis(outerPrefix(receiver.tpe))) case This(_) => ref(outerParamAccessor(cls)) // will be rewired to outer argument of secondary constructor in phase Constructors diff --git a/tests/pending/pos/i1865.scala b/tests/pending/pos/i1865.scala new file mode 100644 index 000000000000..1b77558ff450 --- /dev/null +++ b/tests/pending/pos/i1865.scala @@ -0,0 +1,24 @@ +class AbsCell { + type T = Node + class Node +} + +object Test { + def test: Unit = { + val cell = new AbsCell + new cell.T + } +} + +class AbsCell2 { + type T = Node + val value: T = value + def set(x: T): Unit = {} + class Node +} +object init { + def main = { + val cell = new AbsCell2 { val init = new Node } + cell set (new cell.T) + } +} From a7e88df553be9dd2593dbb8581630ae815eedfb1 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 4 Jan 2017 17:22:47 +0700 Subject: [PATCH 2/2] Address reviewer comments --- compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala | 2 +- tests/{pending => }/pos/i1865.scala | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{pending => }/pos/i1865.scala (100%) diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 497b73807ab8..c2aacf826380 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -276,6 +276,7 @@ object ExplicitOuter { if (tpe.prefix eq NoPrefix) cls.owner.enclosingClass.thisType else tpe.prefix case _ => + // Need to be careful to dealias before erasure, otherwise we lose prefixes. outerPrefix(tpe.underlying(ctx.withPhaseNoLater(ctx.erasurePhase))) } case tpe: TypeProxy => @@ -339,7 +340,6 @@ object ExplicitOuter { val cls = fun.symbol.owner.asClass def outerArg(receiver: Tree): Tree = receiver match { case New(_) | Super(_, _) => - println(i"outerarg: ${receiver.tpe} --> ${outerPrefix(receiver.tpe)} at ${ctx.phase}") singleton(fixThis(outerPrefix(receiver.tpe))) case This(_) => ref(outerParamAccessor(cls)) // will be rewired to outer argument of secondary constructor in phase Constructors diff --git a/tests/pending/pos/i1865.scala b/tests/pos/i1865.scala similarity index 100% rename from tests/pending/pos/i1865.scala rename to tests/pos/i1865.scala