Skip to content

Unsoundness due to GADT bounds ignoring type (un)injectivity #5658

Closed
@abgruszecki

Description

@abgruszecki

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions