Skip to content

Commit e0853b3

Browse files
committed
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.
1 parent d9b6559 commit e0853b3

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ abstract class ExplicitOuter extends InfoTransform
4646
private def haveSameOuter(parent: Type, clazz: Symbol) = parent match {
4747
case TypeRef(pre, sym, _) =>
4848
val owner = clazz.owner
49+
50+
//println(s"have same outer $parent $clazz $sym ${sym.owner} $owner $pre")
4951

5052
sym.isClass && owner.isClass &&
51-
owner == sym.owner &&
53+
(owner isSubClass sym.owner) &&
5254
owner.thisType =:= pre
55+
5356
case _ => false
5457
}
5558

@@ -480,7 +483,7 @@ abstract class ExplicitOuter extends InfoTransform
480483
val vparamss1 =
481484
if (isInner(clazz)) { // (4)
482485
val outerParam =
483-
sym.newValueParameter(nme.OUTER, sym.pos) setInfo outerField(clazz).info
486+
sym.newValueParameter(nme.OUTER, sym.pos) setInfo clazz.outerClass.thisType
484487
((ValDef(outerParam) setType NoType) :: vparamss.head) :: vparamss.tail
485488
} else vparamss
486489
super.transform(copyDefDef(tree)(vparamss = vparamss1))

test/files/run/outertest.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// A test for the case where the outer field of class B#J should be eliminated.
2+
// You can verify this by running a javap on B.J
3+
abstract class A {
4+
5+
abstract class I {
6+
7+
}
8+
9+
val foo = "foo"
10+
11+
}
12+
13+
class B extends A {
14+
15+
class J extends I {
16+
val bar = foo
17+
}
18+
19+
}
20+
21+
object Test extends App {
22+
23+
val b = new B
24+
assert((new b.J).bar == b.foo)
25+
26+
}

0 commit comments

Comments
 (0)