I have a simple case to test the type inference capability of scala:
trait Super1[S] {
final type Out = this.type
final val out: Out = this
}
trait Super2[S] extends Super1[S] {
final type SS = S
}
case class A[S](k: S) extends Super2[S] {}
val a = A("abc")
implicitly[a.type =:= a.out.type]
// success
implicitly[a.Out =:= a.out.Out]
// success
implicitly[a.SS =:= a.out.SS]
implicitly[a.SS <:< a.out.SS]
implicitly[a.out.SS <:< a.SS]
// oops
The error for the last 4 lines looks like this:
[Error] /home/peng/git-spike/scalaspike/common/src/test/scala/com/tribbloids/spike/scala_spike/AbstractType/InferInheritance.scala:28: Cannot prove that a.SS =:= Super2.this.SS.
[Error] /home/peng/git-spike/scalaspike/common/src/test/scala/com/tribbloids/spike/scala_spike/AbstractType/InferInheritance.scala:29: Cannot prove that a.SS <:< Super2.this.SS.
[Error] /home/peng/git-spike/scalaspike/common/src/test/scala/com/tribbloids/spike/scala_spike/AbstractType/InferInheritance.scala:30: Cannot prove that Super2.this.SS <:< a.SS.
three errors found
Clearly scala compiler screwed up on these cases: if I move:
final type Out = this.type
final val out: Out = this
to be under Super2 it will compile successfully. My question is that: why the status quo inference algorithm won't work in this case? and how can I rewrite my code to circumvent this problem of the compiler?