Open
Description
It seems that type parameter bounds on existential types are not used to enforce the exhaustiveness of pattern matching. This causes errors at runtime if you forget to supply a case, demonstrated below. While it is possible to workaround this, the current behavior is undesirable as it leads to runtime errors the compiler should prevent.
sealed trait Letter
object Letter {
sealed trait Vowel extends Letter
sealed trait Consonant extends Letter
}
case object Aye extends Letter.Vowel
case object Bee extends Letter.Consonant
case object Cee extends Letter.Consonant
case object Dee extends Letter.Consonant
case object Eee extends Letter.Vowel
case class Foo[A <: Letter](letter: A)
def unFooVowel(foo: Foo[_ <: Letter.Vowel]): Char = foo.letter match {
case Aye => 'a'
// No warning for non-exhaustive case!
// case Eee => 'e'
}
unFooVowel(Foo(Eee))
// scala.MatchError: Eee
// Workaround using covariance
case class Bar[+A <: Letter](letter: A)
def unBarVowel(bar: Bar[Letter.Vowel]): Char = bar.letter match {
case Aye => 'a'
// Proper warning for non-exhaustive case.
// case Eee => 'e'
}