У меня есть простой случай для проверки возможности вывода типа 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
Ошибка для последних 4 строк выглядит так:
[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
Ясно, что компилятор scala облажался в этих случаях: если я перейду:
final type Out = this.type
final val out: Out = this
чтобы быть под Super2
, он будет успешно скомпилирован. Мой вопрос таков: почему алгоритм вывода о статус-кво не будет работать в этом случае? и как мне переписать свой код, чтобы обойти эту проблему компилятора?