summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-09-28 15:02:24 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2016-09-30 11:06:07 +0200
commit96fe4c334589aaf9e5de4288cd140d3d01794dc5 (patch)
tree4593f6d5625010ab86cd5d7a96da2c6a587943c7
parent1f6006d0d4f8edf4db04915702f8b7e3c8ca1f5e (diff)
downloadscala-96fe4c334589aaf9e5de4288cd140d3d01794dc5.tar.gz
scala-96fe4c334589aaf9e5de4288cd140d3d01794dc5.tar.bz2
scala-96fe4c334589aaf9e5de4288cd140d3d01794dc5.zip
Error message for super calls to indirect java parent interfaces
Super calls to indirect java parent interfaces cannot be emitted, an error message is emitted during SuperAccessors. The error message was missing if the super call was non-qualified, resulting in an assertion failure in the backend.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala4
-rw-r--r--test/junit/scala/lang/traits/BytecodeTest.scala12
2 files changed, 14 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 963a9dea02..8b1b2f35c5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -148,7 +148,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
absSym =>
reporter.error(sel.pos, s"${sym.fullLocationString} cannot be directly accessed from $clazz because ${absSym.owner} redeclares it as abstract")
}
- } else if (mix != tpnme.EMPTY) {
+ } else {
// SD-143: a call super[T].m that resolves to A.m cannot be translated to correct bytecode if
// - A is a class (not a trait / interface), but not the direct superclass. Invokespecial
// would select an overriding method in the direct superclass, rather than A.m.
@@ -162,7 +162,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
else hasClassOverride(member, subclass.superClass)
}
val owner = sym.owner
- if (!owner.isTrait && owner != clazz.superClass && hasClassOverride(sym, clazz.superClass)) {
+ if (mix != tpnme.EMPTY && !owner.isTrait && owner != clazz.superClass && hasClassOverride(sym, clazz.superClass)) {
reporter.error(sel.pos,
s"cannot emit super call: the selected $sym is declared in $owner, which is not the direct superclass of $clazz.\n" +
s"An unqualified super call (super.${sym.name}) would be allowed.")
diff --git a/test/junit/scala/lang/traits/BytecodeTest.scala b/test/junit/scala/lang/traits/BytecodeTest.scala
index cf658288c4..5c01ebc6b2 100644
--- a/test/junit/scala/lang/traits/BytecodeTest.scala
+++ b/test/junit/scala/lang/traits/BytecodeTest.scala
@@ -366,6 +366,18 @@ class BytecodeTest extends BytecodeTesting {
val ins5 = getMethod(c5, "m").instructions
assert(ins5 contains Invoke(INVOKESTATIC, "AS", "m$", "(LAS;)I", true), ins5.stringLines)
}
+
+ @Test
+ def sd224(): Unit = {
+ val jCode = List("interface T { default int f() { return 1; } }" -> "T.java")
+ val code =
+ """trait U extends T
+ |class C extends U { def t = super.f }
+ """.stripMargin
+ val msg = "unable to emit super call unless interface T (which declares method f) is directly extended by class C"
+ val cls = compileClasses(code, jCode, allowMessage = _.msg contains msg)
+ assertEquals(cls, Nil)
+ }
}
object invocationReceiversTestCode {