Skip to content

Unsoundness from overriding vals #16092

Closed
@howtonotwin

Description

@howtonotwin

Tested on Dotty 3.2.0 and 3.2.1-RC2 (both via Scastie). What it says on the tin: overriding a val basically makes paths containing that val unstable. I searched the Dotty issue tracker for this issue and didn't find it, but I was expecting that a (serious?) soundness failure would be there. So this might be a duplicate.

Code

trait X {
  type T
  def process(t: T): Unit
}

class Z(val x: X, val t: x.T) {
  def process(): Unit = x.process(t)
}
class Evil(x1: X, x2: X, t: x1.T) extends Z(x1, t) {
  override val x: X = x2 // breaks connection between x and t
}
// alarm bells should be ringing by now

// taking it to its conclusion...
object x1 extends X {
  override type T = Int
  override def process(t: T): Unit = println("Int: " + t)
}
object x2 extends X {
  override type T = String
  override def process(t: T): Unit = println("String: " + t)
}
new Evil(x1, x2, 42).process() // BOOM: basically did x2.process(42)

Output

No compiler error, and a ClassCastException when run.

Expectation

Compiler error of some kind.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:typeritype:bugitype:soundnessSoundness bug (it lets us compile code that crashes at runtime with a ClassCastException)

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions