Lately I was studying the issue #16092 because I have the feeling that override val got the blame for a crime it did not commit. Sure, it has a bad smell in initialisation issues for example. But initialisation is tricky business anyway even without overriding a val. The sentence? Elimination! By the highest court. But where is the evidence? Seems we need a novum here to prove its innocence. From the posts in issue #16092 it became clear to me that smoke is there, but i see no gun. No one was able to construct the example where the override alone caused the problem, it seems always in combination with parameter substitution.
So i tried to eliminate the parameters from the original 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
}
to obtain:
trait X :
type T
def process(t: T): Unit
abstract class Z :
val x: X
val t: x.T
def process(): Unit = x.process(t)
class Evil1(px: X, pt: px.T) extends Z :
val x = px
val t = pt
class Evil2(px1: X, px2: X, pt: px1.T) extends Evil1(px1,pt) :
override val x: X = px2
Looks like a good start, but the compiler complains about the definition of val t in Evil1:
Found: (Evil1.this.pt : Evil1.this.px.T)
Required: Evil1.this.x.T
Is this indeed a valid complaint by the compiler? If so, then the original problem might be in the accepted substitution of the parameters, not in the override val. If not, is this current error a compiler problem then? Or am I completely missing something here?