Search code examples
scalapattern-matchingcompiler-warningstype-parameternon-exhaustive-patterns

Type parameter circumvents match exhaustivity warning


Why does type parameter bound by sealed type seem not to raise exhaustivity warning

sealed trait A
case class B() extends A
case class C(i: Option[Int]) extends A

def f[T <: A](a: T) =
  a match {
    case B() =>
    case C(None) =>
  }

f(C(Some(42))) // throws MatchError

whilst without type parameter

def f(a: A) =
  a match {
    case B() =>
    case C(None) =>
  }

the warning is raised

warning: match may not be exhaustive.
It would fail on the following input: C(Some(_))
    a match {
    ^

Solution

  • Pattern matching

    def f[T <: A](a: T) =
      a match {
        case B() =>
        case C(None) =>
      }
    

    can be exhaustive or not exhaustive depending on T.

    (T <: A doesn't mean that T is B or C, see 1 2 3).

    According to specification

    If the selector of a pattern match is an instance of a sealed class, the compilation of pattern matching can emit warnings which diagnose that a given set of patterns is not exhaustive, i.e. that there is a possibility of a MatchError being raised at run-time.

    So compiler can but not must emit warning.