Match may not be exhaustive. Why?



I have the following code:

  sealed trait TT
  sealed case class XT() extends TT
  sealed case class YT() extends TT

  sealed trait MapI[T]

  sealed class Constant[T](v:T) extends MapI[T] {
    val name: String = s"Constant(${v.toString})"
  sealed case class A(v: XT) extends Constant[XT](v)
  sealed case class B(v: XT) extends Constant[XT](v)
  sealed case class C(v: XT) extends Constant[XT](v)

  def testMapI(e:Constant[XT]): String = e match {
    case A(v) => v.toString
    case B(v) => v.toString
    case C(v) => v.toString
    //case (_:Constant[_]) => "XT"

And I get:

match may not be exhaustive.
[warn] It would fail on the following input: Constant()
[warn]   def testMapI(e:Constant[XT]): String = e match {

If I activate the case (_:Constant[_]) => "XT", no compiler warning. I tried using case objects and set sealed in all places I thought could help, but nothing helped.

I assumed that setting the parameter to Constant[XT] means that we cannot have any other type of Constant. This seems to be correct because if I use the case.

case (_:Constant[YT]) => "XT"

I get :

fruitless type test: a value of type Constant[XT] cannot also be a Constant[YT] (but still might match its erasure)
[warn]     case (_:Constant[YT]) => "XT"
[warn]             ^

So what what is the type _ in case (_:Constant[_]) => "XT"? Is this an erasure issue?


testMapI(new Constant(XT())) // MatchError

You probably meant sealed abstract class Constant[T].


@Jasper-M I only have the requirement that it be a base class for use in pattern
matching. Note that here we really don’t have any abstract members.

But now I (finally) understand why it has to be abstract.

Thank you.