Skip to content

Commit

Permalink
Disallow mixins where super calls bind to vals (#16908)
Browse files Browse the repository at this point in the history
Forward port of scala/scala#10268
Fixes #16704
  • Loading branch information
sjrd committed Feb 14, 2023
2 parents e836f22 + a53b185 commit 8d674ba
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
Expand Up @@ -119,6 +119,9 @@ object ResolveSuper {
report.error(IllegalSuperAccessor(base, memberName, targetName, acc, accTp, other.symbol, otherTp), base.srcPos)
bcs = bcs.tail
}
if sym.is(Accessor) then
report.error(
em"parent ${acc.owner} has a super call which binds to the value ${sym.showFullName}. Super calls can only target methods.", base)
sym.orElse {
val originalName = acc.name.asTermName.originalOfSuperAccessorName
report.error(em"Member method ${originalName.debugString} of mixin ${acc.owner} is missing a concrete super implementation in $base.", base.srcPos)
Expand Down
17 changes: 17 additions & 0 deletions tests/neg/t12715.scala
@@ -0,0 +1,17 @@
trait A { def f: String }
trait B extends A { def f = "B" }
trait C extends A { override val f = "C" }
trait D extends C { override val f = "D" }
trait E extends A, B { def d = super.f }
final class O1 extends B, C, D, E // error: parent trait E has a super call which binds to the value D.f. Super calls can only target methods.
final class O2 extends B, C, E, D // error: parent trait E has a super call which binds to the value C.f. Super calls can only target methods.
final class O3 extends B, E, C, D

object Main:
def main(args: Array[String]): Unit =
println(O1().f) // D
println(O2().f) // D
println(O3().f) // D
println(O3().d) // B
O1().d // was: NoSuchMethodError: 'java.lang.String D.f$(D)'
O2().d // was: NoSuchMethodError: 'java.lang.String C.f$(C)'
16 changes: 16 additions & 0 deletions tests/neg/t12715b.scala
@@ -0,0 +1,16 @@
trait B:
def f: Float = 1.0f

class A(override val f: Float) extends B

trait C extends B:
abstract override val f = super.f + 100.0f

trait D extends B:
abstract override val f = super.f + 1000.0f

class ACD10 extends A(10.0f) with C with D // error: parent trait D has a super call to method B.f, which binds to the value C.f. Super calls can only target methods.

object Test:
def main(args: Array[String]): Unit =
new ACD10 // was: NoSuchMethodError: 'float C.f$(C)'

0 comments on commit 8d674ba

Please sign in to comment.