Skip to content

Commit 30e0985

Browse files
committed
Revert pruning of redundant Java parents
This partially reverts the fix for SI-5278 made in 7a99c03. The original motivation for this case to avoid bytecode that stretched platform limitations in Android. For super calls to Scala defined trait methods, we won't use `invokespecial`, but rather use `invokestatic` to a static trait implementation method. As such, we can continue to prune redundant Scala interfaces. It might be worth considering removing the pruning of redundant parents altoghether, though: - We no longer include `ScalaObject` as a parent of every class, which was mentioned as a problem in SI-5728. - Scala 2.12 has left Android behind for the time being due to use of Java 8 facilities. - javac doesn't do this, so why should we?
1 parent 75c43b1 commit 30e0985

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,17 +189,19 @@ abstract class Erasure extends AddInterfaces
189189

190190
/* Drop redundant types (ones which are implemented by some other parent) from the immediate parents.
191191
* This is important on Android because there is otherwise an interface explosion.
192+
* This is now restricted to Scala defined ancestors: a Java defined ancestor may need to be listed
193+
* as an immediate parent to support an `invokespecial`.
192194
*/
193195
def minimizeParents(parents: List[Type]): List[Type] = if (parents.isEmpty) parents else {
194-
def isInterfaceOrTrait(sym: Symbol) = sym.isInterface || sym.isTrait
196+
def isRedundantParent(sym: Symbol) = (sym.isInterface || sym.isTrait) && !sym.isJavaDefined
195197

196198
var rest = parents.tail
197199
var leaves = collection.mutable.ListBuffer.empty[Type] += parents.head
198200
while(rest.nonEmpty) {
199201
val candidate = rest.head
200202
val nonLeaf = leaves exists { t => t.typeSymbol isSubClass candidate.typeSymbol }
201203
if(!nonLeaf) {
202-
leaves = leaves filterNot { t => isInterfaceOrTrait(t.typeSymbol) && (candidate.typeSymbol isSubClass t.typeSymbol) }
204+
leaves = leaves filterNot { t => isRedundantParent(t.typeSymbol) && (candidate.typeSymbol isSubClass t.typeSymbol) }
203205
leaves += candidate
204206
}
205207
rest = rest.tail

0 commit comments

Comments
 (0)