-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of exhaustivity and redundancy check #1364
Conversation
29299d9
to
34484dc
Compare
Neither scalac nor this algorithm can handle following cases about GADT. Both are exhaustive, but the compiler incorrectly reports non-exhaustive. AFAIK, only Haskell handles that in the latest paper(2015), which depends on the type constraint solver. Example 1: sealed trait Expr[+T]
case class IntExpr(x: Int) extends Expr[Int]
case class BooleanExpr(b: Boolean) extends Expr[Boolean]
object Test {
def foo[T](x: Expr[T], y: Expr[T]) = (x, y) match {
case (IntExpr(_), IntExpr(_)) =>
case (BooleanExpr(_), BooleanExpr(_)) =>
}
} Example 2: sealed trait Nat[+T]
case class Zero() extends Nat[Nothing]
case class Succ[T]() extends Nat[T]
sealed trait Vect[+N <: Nat[_], +T]
case class VN[T]() extends Vect[Zero, T]
case class VC[T, N <: Nat[_]](x: T, xs: Vect[N, T]) extends Vect[Succ[N], T]
object Test {
def foo[N <: Nat[_], A, B](v1: Vect[N, A], v2: Vect[N, B]) = (v1, v2) match {
case (VN(), VN()) => 1
case (VC(x, xs), VC(y, ys)) => 2
}
} |
/rebuild |
34484dc
to
552664e
Compare
The two examples above are in fact both non-exhaustive in Dotty, due to the existence of union types. In Scala, they are exhaustive. |
Can you give an example of a case that isn't covered in dotty in these examples? |
For the first case, For the second case, let |
Put it another way, union types break the definiteness of type variables -- the same type variable may take arbitrarily different types in different positions. That's the cause of the discrepancy between Scala and Dotty in the two code examples above. For example, for the generic product type Subtyping also breaks definiteness of type variables to some extent, but not so fundamentally as union types. For example, with subtyping we know for all instantiations of the pair |
I need to think more about this but:
If Combining variance and GADTs is tricky, see http://lampwww.epfl.ch/~hmiller/scala2013/resources/pdfs/paper5.pdf |
b1afadb
to
d322d8c
Compare
d322d8c
to
4893ecb
Compare
/rebuild |
4893ecb
to
cc02243
Compare
LGTM |
These are from scala/scala3#1364 and they do indeed work correctly for Scala 2 but not for Scala 3. #fixed-in-nsc
Todos
Fix following scalac open issues
Links