Current treatment of type constructors by constraint inference is blatantly unsound, as we simply ignore the problem of constructor injectivity. As an example, following test causes a runtime exception:
object Test {
sealed trait EQ[A, B]
final case class Refl[T]() extends EQ[T, T]
def absurd[F[_], X, Y](eq: EQ[F[X], F[Y]], x: X): Y = eq match {
case Refl() => x
}
var ex: Exception = _
try {
type Unsoundness[X] = Int
val s: String = absurd[Unsoundness, Int, String](Refl(), 0)
} catch {
case e: ClassCastException => ex = e
}
def main(args: Array[String]) =
assert(ex != null)
}
(https://github.com/dotty-staging/dotty/blob/d1fa5d73c4194448e1ab0d4d4e39a764b6e1f651/tests/run/gadt-injectivity-unsoundness.scala)
This was intentionally extracted out of #5611.