Skip to content

Missing override check leads to ClassCastException #11719

Closed
@smarter

Description

@smarter
class Base
class Sub extends Base

trait A[+T] {
  def get(f: T => Boolean): Unit = {}
}

trait B extends A[Base] {
  override def get(f: Base => Boolean): Unit = f(new Base)
}

class C extends B with A[Sub]

object Test {
  def main(args: Array[String]): Unit = {
    val c = new C
    c.get((x: Sub) => true) // ClassCastException: Base cannot be cast to Sub
  }
}

In Scala 2 this is rejected (at erasure):

error: name clash between inherited members:
def get(f: Sub => Boolean): Unit in trait A and
override def get(f: Base => Boolean): Unit in trait B
have same type after erasure: (f: Function1): Unit
class C extends B with A[Sub]
      ^
1 error

And a simplified example is rejected by dotty at RefChecks in checkMemberTypesOK:

class Base
class Sub extends Base

trait A[+T] {
  def get: T = ???
}

trait B extends A[Base] {
  override def get: Base = new Base
}

class C extends B with A[Sub]
-- Error: try/dg3.scala:12:6 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
12 |class C extends B with A[Sub]
   |      ^
   |      method get in trait B is not a legal implementation of `get` in class C
   |        its type             => Base
   |        does not conform to  => Sub

The difference is that all parameter-less overrides are considered matching denotations (since they can never be valid overloads), but in the original example, from the point of view of C, the get in A and the one in B are overloads, since they don't have matching signatures as seen from C.

Hopefully this is fixable by tweaking the checkMemberTypesOK logic but I don't have the bandwidth to investigate this for now, do you think you could take a look @odersky ?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions