diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala | 4 | ||||
-rw-r--r-- | test/junit/scala/lang/traits/BytecodeTest.scala | 12 |
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 { |