Skip to content

Commit

Permalink
Removes redundant outers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
odersky committed Jul 20, 2012
1 parent d9b6559 commit e0853b3
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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))
Expand Down
26 changes: 26 additions & 0 deletions test/files/run/outertest.scala
Original file line number Diff line number Diff line change
@@ -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)

}

0 comments on commit e0853b3

Please sign in to comment.