From 152e4690edd3e5ad484519baccdf679cfa0919ed Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Sun, 18 Dec 2016 00:56:18 +0100 Subject: fix #1820: make sure outer of traits implemented --- .../dotty/tools/dotc/transform/ExplicitOuter.scala | 19 ++++++++++++------- tests/run/i1820.check | 1 + tests/run/i1820.scala | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 tests/run/i1820.check create mode 100644 tests/run/i1820.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 5463d5080..e792518ce 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -81,14 +81,19 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf !needsOuterAlways(cls) && impl.existsSubTree(referencesOuter(cls, _))) ensureOuterAccessors(cls) - if (hasOuter(cls)) { + + val hasOuterFlag = hasOuter(cls) + if (hasOuterFlag || cls.mixins.exists(needsOuterIfReferenced)) { val newDefs = new mutable.ListBuffer[Tree] - if (isTrait) - newDefs += DefDef(outerAccessor(cls).asTerm, EmptyTree) - else { - val outerParamAcc = outerParamAccessor(cls) - newDefs += ValDef(outerParamAcc, EmptyTree) - newDefs += DefDef(outerAccessor(cls).asTerm, ref(outerParamAcc)) + + if (hasOuterFlag) { + if (isTrait) + newDefs += DefDef(outerAccessor(cls).asTerm, EmptyTree) + else { + val outerParamAcc = outerParamAccessor(cls) + newDefs += ValDef(outerParamAcc, EmptyTree) + newDefs += DefDef(outerAccessor(cls).asTerm, ref(outerParamAcc)) + } } for (parentTrait <- cls.mixins) { diff --git a/tests/run/i1820.check b/tests/run/i1820.check new file mode 100644 index 000000000..789819226 --- /dev/null +++ b/tests/run/i1820.check @@ -0,0 +1 @@ +a diff --git a/tests/run/i1820.scala b/tests/run/i1820.scala new file mode 100644 index 000000000..bc4f63d9b --- /dev/null +++ b/tests/run/i1820.scala @@ -0,0 +1,17 @@ +class A { + val a = "a" + trait Inner { + def f = println(a) + def h = 3 + } +} + +class Inner extends O.a.Inner + +object O { + val a = new A + + def main(args: Array[String]): Unit = { + (new Inner).f + } +} -- cgit v1.2.3 From bfabceeb1d19848e86f69019a4614c3653420ccc Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Mon, 19 Dec 2016 14:08:36 +0100 Subject: Fix #1820: condition of whether generates outer Previously, we don't generate `outer` for the anonymous class `new Inner2 {}`. This is incorrect, as `Inner2 {}` extends `A.Inner`, which requires an outer. trait A { val a = "a" trait Inner { def f = println(a) def h = 3 } } trait B extends A { trait Inner2 extends Inner new Inner2 {} } --- .../dotty/tools/dotc/transform/ExplicitOuter.scala | 3 ++- tests/run/i1820.scala | 4 ++-- tests/run/i1820b.check | 1 + tests/run/i1820b.scala | 19 +++++++++++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 tests/run/i1820b.check create mode 100644 tests/run/i1820b.scala diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index e792518ce..007210926 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -79,7 +79,8 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf val isTrait = cls.is(Trait) if (needsOuterIfReferenced(cls) && !needsOuterAlways(cls) && - impl.existsSubTree(referencesOuter(cls, _))) + (cls.mixins.exists(needsOuterIfReferenced) || + impl.existsSubTree(referencesOuter(cls, _)))) ensureOuterAccessors(cls) val hasOuterFlag = hasOuter(cls) diff --git a/tests/run/i1820.scala b/tests/run/i1820.scala index bc4f63d9b..b39e6d108 100644 --- a/tests/run/i1820.scala +++ b/tests/run/i1820.scala @@ -6,9 +6,9 @@ class A { } } -class Inner extends O.a.Inner +class Inner extends Test.a.Inner -object O { +object Test { val a = new A def main(args: Array[String]): Unit = { diff --git a/tests/run/i1820b.check b/tests/run/i1820b.check new file mode 100644 index 000000000..789819226 --- /dev/null +++ b/tests/run/i1820b.check @@ -0,0 +1 @@ +a diff --git a/tests/run/i1820b.scala b/tests/run/i1820b.scala new file mode 100644 index 000000000..3452b6158 --- /dev/null +++ b/tests/run/i1820b.scala @@ -0,0 +1,19 @@ +trait A { + val a = "a" + trait Inner { + def f = println(a) + def h = 3 + } +} + +trait B extends A { + trait Inner2 extends Inner + def g = new Inner2 {} +} + +object Test { + def main(args: Array[String]): Unit = { + val b = new B {} + b.g.f + } +} -- cgit v1.2.3 From 1d534c54b5150868818609a2055fdc11e82643fe Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Mon, 19 Dec 2016 16:50:32 +0100 Subject: refine previous commit --- compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 007210926..16010d439 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -79,8 +79,7 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf val isTrait = cls.is(Trait) if (needsOuterIfReferenced(cls) && !needsOuterAlways(cls) && - (cls.mixins.exists(needsOuterIfReferenced) || - impl.existsSubTree(referencesOuter(cls, _)))) + impl.existsSubTree(referencesOuter(cls, _))) ensureOuterAccessors(cls) val hasOuterFlag = hasOuter(cls) @@ -187,6 +186,7 @@ object ExplicitOuter { private def needsOuterAlways(cls: ClassSymbol)(implicit ctx: Context): Boolean = needsOuterIfReferenced(cls) && (!hasLocalInstantiation(cls) || // needs outer because we might not know whether outer is referenced or not + cls.mixins.exists(needsOuterIfReferenced) || // needs outer for parent traits cls.classInfo.parents.exists(parent => // needs outer to potentially pass along to parent needsOuterIfReferenced(parent.classSymbol.asClass))) -- cgit v1.2.3 From c2bc63799199db517281935ebc3f56d29ba3c932 Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Tue, 20 Dec 2016 13:42:00 +0100 Subject: address review: rename hasOuterFlag to clsHasOuter --- compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 16010d439..1eb12e9de 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -82,11 +82,11 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf impl.existsSubTree(referencesOuter(cls, _))) ensureOuterAccessors(cls) - val hasOuterFlag = hasOuter(cls) - if (hasOuterFlag || cls.mixins.exists(needsOuterIfReferenced)) { + val clsHasOuter = hasOuter(cls) + if (clsHasOuter || cls.mixins.exists(needsOuterIfReferenced)) { val newDefs = new mutable.ListBuffer[Tree] - if (hasOuterFlag) { + if (clsHasOuter) { if (isTrait) newDefs += DefDef(outerAccessor(cls).asTerm, EmptyTree) else { -- cgit v1.2.3