Skip to content

Commit ed38fbc

Browse files
committed
Revert pruning of redundant interfaces
This reverts the fix for SI-5278 made in 7a99c03 and later refined. Direct parents enable use of `invokespecial` in the JVM, so are not redundant. The motivating use case was the proliferation of the `ScalaObject` parent in Android. We no longer include that interfaces as a parent of any class, and Scala 2.12 has left Android behind for the time being due to use of Java 8 facilities.
1 parent e82b0a9 commit ed38fbc

File tree

2 files changed

+3
-32
lines changed

2 files changed

+3
-32
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -234,18 +234,10 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
234234

235235
val allParents = classParents ++ classSym.annotations.flatMap(newParentForAnnotation)
236236

237-
// We keep the superClass when computing minimizeParents to eliminate more interfaces.
238-
// Example: T can be eliminated from D
239-
// trait T
240-
// class C extends T
241-
// class D extends C with T
242-
val interfaces = erasure.minimizeParents(allParents) match {
237+
val interfaces = allParents match {
243238
case superClass :: ifs if !isInterfaceOrTrait(superClass.typeSymbol) =>
244239
ifs
245240
case ifs =>
246-
// minimizeParents removes the superclass if it's redundant, for example:
247-
// trait A
248-
// class C extends Object with A // minimizeParents removes Object
249241
ifs
250242
}
251243
interfaces.map(_.typeSymbol)

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

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -187,26 +187,6 @@ abstract class Erasure extends AddInterfaces
187187

188188
private def isErasedValueType(tpe: Type) = tpe.isInstanceOf[ErasedValueType]
189189

190-
/* Drop redundant types (ones which are implemented by some other parent) from the immediate parents.
191-
* This is important on Android because there is otherwise an interface explosion.
192-
*/
193-
def minimizeParents(parents: List[Type]): List[Type] = if (parents.isEmpty) parents else {
194-
def isInterfaceOrTrait(sym: Symbol) = sym.isInterface || sym.isTrait
195-
196-
var rest = parents.tail
197-
var leaves = collection.mutable.ListBuffer.empty[Type] += parents.head
198-
while(rest.nonEmpty) {
199-
val candidate = rest.head
200-
val nonLeaf = leaves exists { t => t.typeSymbol isSubClass candidate.typeSymbol }
201-
if(!nonLeaf) {
202-
leaves = leaves filterNot { t => isInterfaceOrTrait(t.typeSymbol) && (candidate.typeSymbol isSubClass t.typeSymbol) }
203-
leaves += candidate
204-
}
205-
rest = rest.tail
206-
}
207-
leaves.toList
208-
}
209-
210190

211191
/** The Java signature of type 'info', for symbol sym. The symbol is used to give the right return
212192
* type for constructors.
@@ -224,12 +204,11 @@ abstract class Erasure extends AddInterfaces
224204
case _ => tps
225205
}
226206

227-
val minParents = minimizeParents(parents)
228207
val validParents =
229208
if (isTraitSignature)
230209
// java is unthrilled about seeing interfaces inherit from classes
231-
minParents filter (p => isInterfaceOrTrait(p.typeSymbol))
232-
else minParents
210+
parents filter (p => isInterfaceOrTrait(p.typeSymbol))
211+
else parents
233212

234213
val ps = ensureClassAsFirstParent(validParents)
235214

0 commit comments

Comments
 (0)