aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2016-12-20 17:13:26 +0100
committerGitHub <noreply@github.com>2016-12-20 17:13:26 +0100
commitafa83099a2300fcd09afe6514f9112c75f9fb4dc (patch)
treeb7b08c18e7d2d71ca70ad63af4db036924294ad4
parente23c2783521c5fb0808da3bf3ebc5e0bdd09d33d (diff)
parentc2bc63799199db517281935ebc3f56d29ba3c932 (diff)
downloaddotty-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.scala20
-rw-r--r--tests/run/i1820.check1
-rw-r--r--tests/run/i1820.scala17
-rw-r--r--tests/run/i1820b.check1
-rw-r--r--tests/run/i1820b.scala19
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
+ }
+}