summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 {