diff options
author | odersky <odersky@gmail.com> | 2016-12-20 17:13:26 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-20 17:13:26 +0100 |
commit | afa83099a2300fcd09afe6514f9112c75f9fb4dc (patch) | |
tree | b7b08c18e7d2d71ca70ad63af4db036924294ad4 | |
parent | e23c2783521c5fb0808da3bf3ebc5e0bdd09d33d (diff) | |
parent | c2bc63799199db517281935ebc3f56d29ba3c932 (diff) | |
download | dotty-afa83099a2300fcd09afe6514f9112c75f9fb4dc.tar.gz dotty-afa83099a2300fcd09afe6514f9112c75f9fb4dc.tar.bz2 dotty-afa83099a2300fcd09afe6514f9112c75f9fb4dc.zip |
Merge pull request #1821 from dotty-staging/fix-i1820
Fix #1820: make sure outer of traits implemented
-rw-r--r-- | compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala | 20 | ||||
-rw-r--r-- | tests/run/i1820.check | 1 | ||||
-rw-r--r-- | tests/run/i1820.scala | 17 | ||||
-rw-r--r-- | tests/run/i1820b.check | 1 | ||||
-rw-r--r-- | tests/run/i1820b.scala | 19 |
5 files changed, 51 insertions, 7 deletions
diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 5463d5080..1eb12e9de 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 clsHasOuter = hasOuter(cls) + if (clsHasOuter || 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 (clsHasOuter) { + 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) { @@ -181,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))) 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..b39e6d108 --- /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 Test.a.Inner + +object Test { + val a = new A + + def main(args: Array[String]): Unit = { + (new Inner).f + } +} 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 + } +} |