Skip to content

Commit 92f4e1e

Browse files
committed
Fix bug in minimizeParents, keep all java interfaces
1 parent e6bfbca commit 92f4e1e

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,17 +195,20 @@ abstract class Erasure extends InfoTransform
195195
* as an immediate parent to support an `invokespecial`.
196196
*/
197197
def minimizeParents(parents: List[Type]): List[Type] = if (parents.isEmpty) parents else {
198-
def isRedundantParent(sym: Symbol) = sym.isInterface || sym.isTrait
198+
def isRedundantParent(parent: Symbol, candidate: Symbol) =
199+
!parent.isJavaDefined &&
200+
parent.isTraitOrInterface &&
201+
candidate.isSubClass(parent)
199202

200203
var rest = parents.tail
201204
var leaves = collection.mutable.ListBuffer.empty[Type] += parents.head
202-
while(rest.nonEmpty) {
205+
while (rest.nonEmpty) {
203206
val candidate = rest.head
204207
if (candidate.typeSymbol.isJavaDefined && candidate.typeSymbol.isInterface) leaves += candidate
205208
else {
206209
val nonLeaf = leaves exists { t => t.typeSymbol isSubClass candidate.typeSymbol }
207210
if (!nonLeaf) {
208-
leaves = leaves filterNot { t => isRedundantParent(t.typeSymbol) && (candidate.typeSymbol isSubClass t.typeSymbol) }
211+
leaves = leaves filterNot { t => isRedundantParent(t.typeSymbol, candidate.typeSymbol) }
209212
leaves += candidate
210213
}
211214
}

test/junit/scala/lang/traits/BytecodeTest.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,19 @@ class BytecodeTest extends BytecodeTesting {
379379
assertEquals(cls, Nil)
380380
}
381381

382+
@Test
383+
def noMinimizeJavaInterfaces(): Unit = {
384+
val jCode = List("interface T { default int f() { return 1; } }" -> "T.java")
385+
val code =
386+
"""trait U extends T { override def f() = 2 }
387+
|class C extends T with U { def t = super[T].f }
388+
""".stripMargin
389+
val List(c, u) = compileClasses(code, jCode)
390+
assertEquals(c.interfaces.asScala.toList.sorted, List("T", "U"))
391+
val ins = getMethod(c, "t").instructions
392+
assert(ins contains Invoke(INVOKESPECIAL, "T", "f", "()I", true), ins.stringLines)
393+
}
394+
382395
def ifs(c: ClassNode, expected: List[String]) = assertEquals(expected, c.interfaces.asScala.toList.sorted)
383396
def invSt(m: Method, receiver: String, method: String = "f$", itf: Boolean = true): Unit =
384397
assert(m.instructions contains Invoke(INVOKESTATIC, receiver, method, s"(L$receiver;)I", itf), m.instructions.stringLines)

0 commit comments

Comments
 (0)