Scala pattern match on ADTs may not warn on unreachable code

Viewed 107

I've got a simple ADT (Algebraic Data Type) encoded as:

sealed trait TrafficLight
case object Red extends TrafficLight
case object Green extends TrafficLight
case object Yellow extends TrafficLight

Say, I have a function that returns the name of the colour of a TrafficLight:

  def getColour(tf: TrafficLight): String = tf match {
    case Red    => "red"
    case Green  => "green"
    case Yellow => "yellow"
  }

This works as expected. Now I've matched all cases of TrafficLight in the above function. If I introduce a default match down the bottom of the same method:

  def getColour(tf: TrafficLight): String = tf match {
    case Red    => "red"
    case Green  => "green"
    case Yellow => "yellow"
    case other  => "unknown" //this should not be unreachable
  }

the compiler does not warn me that case other is unreachable. I have also enabled the compiler flag: -Ywarn-dead-code. Does this mean that Scala can't infer that I've covered all the possible values of the TrafficLight ADT?

This seems unlikely because if I change the definition of getColour to:

def blah(tf: TrafficLight): String = tf match {
  case Red    => "red"
  case Green  => "green"
}

the compiler warns me that I've missed a case:

> match may not be exhaustive.
> [error] It would fail on the following input: Yellow
> [error]   def blah(tf: TrafficLight): String = tf match {

I'm using Scala 2.12.5

Is this a bug or have I made a wrong assumption?

1 Answers

You did not covered all possible variants of TrafficLight you just covered all named variants, but you can still pass anonymous class object as argument fe.:

getColour(new TrafficLight {})
Related