summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala28
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala24
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala18
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala2
6 files changed, 33 insertions, 43 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index f385acdb41..cf52ad6636 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -1495,7 +1495,7 @@ abstract class GenICode extends SubComponent {
if (!settings.optimise) {
if (l.tpe <:< BoxedNumberClass.tpe) {
if (r.tpe <:< BoxedNumberClass.tpe) platform.externalEqualsNumNum
- else if (r.tpe <:< BoxedCharacterClass.tpe) platform.externalEqualsNumChar
+ else if (r.tpe <:< BoxedCharacterClass.tpe) platform.externalEqualsNumObject // will be externalEqualsNumChar in 2.12, SI-9030
else platform.externalEqualsNumObject
} else platform.externalEquals
} else {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
index 328ec8a033..a5f33aa786 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
@@ -162,4 +162,32 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
assoc.collectFirst {
case (`nme`.value, LiteralAnnotArg(Constant(value: Symbol))) => value
}).flatten.getOrElse(AnnotationRetentionPolicyClassValue)
+
+ def implementedInterfaces(classSym: Symbol): List[Symbol] = {
+ // Additional interface parents based on annotations and other cues
+ def newParentForAnnotation(ann: AnnotationInfo): Option[Type] = ann.symbol match {
+ case RemoteAttr => Some(RemoteInterfaceClass.tpe)
+ case _ => None
+ }
+
+ def isInterfaceOrTrait(sym: Symbol) = sym.isInterface || sym.isTrait
+
+ val allParents = classSym.info.parents ++ classSym.annotations.flatMap(newParentForAnnotation)
+
+ // We keep the superClass when computing minimizeParents to eliminate more interfaces.
+ // Example: T can be eliminated from D
+ // trait T
+ // class C extends T
+ // class D extends C with T
+ val interfaces = erasure.minimizeParents(allParents) match {
+ case superClass :: ifs if !isInterfaceOrTrait(superClass.typeSymbol) =>
+ ifs
+ case ifs =>
+ // minimizeParents removes the superclass if it's redundant, for example:
+ // trait A
+ // class C extends Object with A // minimizeParents removes Object
+ ifs
+ }
+ interfaces.map(_.typeSymbol)
+ }
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index daf36ce374..062daa4eac 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -1225,7 +1225,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
val equalsMethod: Symbol = {
if (l.tpe <:< BoxedNumberClass.tpe) {
if (r.tpe <:< BoxedNumberClass.tpe) platform.externalEqualsNumNum
- else if (r.tpe <:< BoxedCharacterClass.tpe) platform.externalEqualsNumChar
+ else if (r.tpe <:< BoxedCharacterClass.tpe) platform.externalEqualsNumObject // will be externalEqualsNumChar in 2.12, SI-9030
else platform.externalEqualsNumObject
} else platform.externalEquals
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
index e3b812f413..a0b8d28f18 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
@@ -114,7 +114,7 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
val superClass = if (superClassSym == NoSymbol) None
else Some(classBTypeFromSymbol(superClassSym))
- val interfaces = getSuperInterfaces(classSym).map(classBTypeFromSymbol)
+ val interfaces = implementedInterfaces(classSym).map(classBTypeFromSymbol)
val flags = javaFlags(classSym)
@@ -182,28 +182,6 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
classBType
}
- /**
- * All interfaces implemented by a class, except for those inherited through the superclass.
- *
- * TODO @lry share code with GenASM
- */
- private def getSuperInterfaces(classSym: Symbol): List[Symbol] = {
-
- // Additional interface parents based on annotations and other cues
- def newParentForAnnotation(ann: AnnotationInfo): Symbol = ann.symbol match {
- case RemoteAttr => RemoteInterfaceClass
- case _ => NoSymbol
- }
-
- val superInterfaces0: List[Symbol] = classSym.mixinClasses
- val superInterfaces = existingSymbols(superInterfaces0 ++ classSym.annotations.map(newParentForAnnotation)).distinct
-
- assert(!superInterfaces.contains(NoSymbol), s"found NoSymbol among: ${superInterfaces.mkString(", ")}")
- assert(superInterfaces.forall(s => s.isInterface || s.isTrait), s"found non-interface among: ${superInterfaces.mkString(", ")}")
-
- erasure.minimizeInterfaces(superInterfaces.map(_.info)).map(_.typeSymbol)
- }
-
private def buildNestedInfo(innerClassSym: Symbol): Option[NestedInfo] = {
assert(innerClassSym.isClass, s"Cannot build NestedInfo for non-class symbol $innerClassSym")
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 4373d997b8..de468c0a6d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -1206,22 +1206,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
def serialVUID: Option[Long] = genBCode.serialVUID(clasz.symbol)
- private def getSuperInterfaces(c: IClass): Array[String] = {
-
- // Additional interface parents based on annotations and other cues
- def newParentForAttr(ann: AnnotationInfo): Symbol = ann.symbol match {
- case RemoteAttr => RemoteInterfaceClass
- case _ => NoSymbol
- }
-
- val ps = c.symbol.info.parents
- val superInterfaces0: List[Symbol] = if(ps.isEmpty) Nil else c.symbol.mixinClasses
- val superInterfaces = existingSymbols(superInterfaces0 ++ c.symbol.annotations.map(newParentForAttr)).distinct
-
- if(superInterfaces.isEmpty) EMPTY_STRING_ARRAY
- else mkArray(erasure.minimizeInterfaces(superInterfaces.map(_.info)).map(t => javaName(t.typeSymbol)))
- }
-
var clasz: IClass = _ // this var must be assigned only by genClass()
var jclass: asm.ClassWriter = _ // the classfile being emitted
var thisName: String = _ // the internal name of jclass
@@ -1242,7 +1226,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
val ps = c.symbol.info.parents
val superClass: String = if(ps.isEmpty) JAVA_LANG_OBJECT.getInternalName else javaName(ps.head.typeSymbol)
- val ifaces = getSuperInterfaces(c)
+ val ifaces: Array[String] = implementedInterfaces(c.symbol).map(javaName)(collection.breakOut)
val thisSignature = getGenericSignature(c.symbol, c.symbol.owner)
val flags = mkFlags(
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
index 3bd2e5c4f4..87ad715e4d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
@@ -55,7 +55,7 @@ class LocalOpt(settings: ScalaSettings) {
* @return `true` if unreachable code was eliminated in some method, `false` otherwise.
*/
def methodOptimizations(clazz: ClassNode): Boolean = {
- settings.Yopt.value.nonEmpty && clazz.methods.asScala.foldLeft(false) {
+ !settings.YoptNone && clazz.methods.asScala.foldLeft(false) {
case (changed, method) => methodOptimizations(method, clazz.name) || changed
}
}