bug icon indicating copy to clipboard operation
bug copied to clipboard

Existential type exhaustiveness

Open scabug opened this issue 9 years ago • 1 comments

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'
}

scabug avatar Jun 03 '16 16:06 scabug

Imported From: https://issues.scala-lang.org/browse/SI-9801?orig=1 Reporter: Cary Robbins (carymrobbins)

scabug avatar Jun 03 '16 16:06 scabug