summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-07-20 16:01:01 +0200
committerMartin Odersky <odersky@gmail.com>2012-07-20 16:08:25 +0200
commite0853b3255c5a10793b462c36b62b83963aad17b (patch)
tree4e9244aa3759ae3fd09c02d39ec336e38911cb3b
parentd9b65592df28e8c9655b52c0265f499d757617ba (diff)
downloadscala-e0853b3255c5a10793b462c36b62b83963aad17b.tar.gz
scala-e0853b3255c5a10793b462c36b62b83963aad17b.tar.bz2
scala-e0853b3255c5a10793b462c36b62b83963aad17b.zip
Removes redundant outers
Widens the criterion when outer fields can be omitted. It used to be that sub- and superclass had to be enclosed by the same outer class. Only in that case was the outer field of the class omitted. We now omit if subclass is contained in an outer class that is itself a subclass of the superclasses outer class. See test case "outertest.scala" for an example.
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala7
-rw-r--r--test/files/run/outertest.scala26
2 files changed, 31 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index ab7bbc591b..afbe528b1f 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -46,10 +46,13 @@ abstract class ExplicitOuter extends InfoTransform
private def haveSameOuter(parent: Type, clazz: Symbol) = parent match {
case TypeRef(pre, sym, _) =>
val owner = clazz.owner
+
+ //println(s"have same outer $parent $clazz $sym ${sym.owner} $owner $pre")
sym.isClass && owner.isClass &&
- owner == sym.owner &&
+ (owner isSubClass sym.owner) &&
owner.thisType =:= pre
+
case _ => false
}
@@ -480,7 +483,7 @@ abstract class ExplicitOuter extends InfoTransform
val vparamss1 =
if (isInner(clazz)) { // (4)
val outerParam =
- sym.newValueParameter(nme.OUTER, sym.pos) setInfo outerField(clazz).info
+ sym.newValueParameter(nme.OUTER, sym.pos) setInfo clazz.outerClass.thisType
((ValDef(outerParam) setType NoType) :: vparamss.head) :: vparamss.tail
} else vparamss
super.transform(copyDefDef(tree)(vparamss = vparamss1))
diff --git a/test/files/run/outertest.scala b/test/files/run/outertest.scala
new file mode 100644
index 0000000000..3cc96afa5b
--- /dev/null
+++ b/test/files/run/outertest.scala
@@ -0,0 +1,26 @@
+// A test for the case where the outer field of class B#J should be eliminated.
+// You can verify this by running a javap on B.J
+abstract class A {
+
+ abstract class I {
+
+ }
+
+ val foo = "foo"
+
+}
+
+class B extends A {
+
+ class J extends I {
+ val bar = foo
+ }
+
+}
+
+object Test extends App {
+
+ val b = new B
+ assert((new b.J).bar == b.foo)
+
+}