I am a newcomer to using F-bounded polymorphism in Scala 3. The following code arose when I was trying to use it to prevent type-erasure in a parametrized trait.
sealed trait T0[X <: T0[X]]
case class T1() extends T0[T1]
case class T2() extends T0[T2]
def hCast[X <: T0[X], Y <: T0[Y]](y : Y) : Option[X] = {
y match {
case x : X => {
println("check passed")
Some(x)
}
case _ => None
}
}
The Scala compiler produces a stack-overflow exception when compiling / type-checking this code (Scalastie link). In particular, the Scala 3 compiler outputs the following stacktrace:
java.lang.StackOverflowError
dotty.tools.dotc.core.Types$Type.dealias(Types.scala:1461)
dotty.tools.dotc.core.Definitions.isTupleNType(Definitions.scala:1725)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2924)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2931)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2931)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2931)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2927)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2927)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2927)
dotty.tools.dotc.core.TypeComparer.invariantDisjoint$1(TypeComparer.scala:2860)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint$$anonfun$3(TypeComparer.scala:2875)
scala.collection.LazyZip3.exists(LazyZipOps.scala:235)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2866)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2927)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint(TypeComparer.scala:2927)
dotty.tools.dotc.core.TypeComparer.invariantDisjoint$1(TypeComparer.scala:2860)
dotty.tools.dotc.core.TypeComparer.provablyDisjoint$$anonfun$3(TypeComparer.scala:2875)
<...>
I’m curious if there is a good explanation about this compiler behavior. Alternatively, I know I can use TypeTest[A, B]
to prevent type-erasure as well (as long as A
and B
themselves are not parametric), but it seems to me that some use-cases of TypeTest
would over-lap with F-bounded polymorphism, but the two are somewhat incompatible due to how the above code is rejected by the scala compiler. Any help would be appreciated.