Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning Match may not be exhaustive

I was trying out below code:

  val set1 = Set(1,2,3,4,5,67,8)
  val TRUE_BOOLEAN = true
  val FALSE_BOOLEAN = false
  set1.contains(4) match {
    case TRUE_BOOLEAN => println("Element found")
    case FALSE_BOOLEAN => println("Element not found")
  }

But, when i am trying to run it in IntelliJ, it is giving below warning in Messages tab:

Warning:(11, 16) match may not be exhaustive.
It would fail on the following inputs: false, true
  set1.contains(4) match {

Whereas, if i use true and false instead of TRUE_BOOLEAN and FALSE_BOOLEAN, i am not getting any warning.

set1.contains(4) match {
    case true => println("Element found")
    case false => println("Element not found")
  }

Can someone please explain the reason for this warning and why does it goes away with true and false.

like image 763
mukesh210 Avatar asked Dec 19 '18 17:12

mukesh210


1 Answers

It produces a warning, because it cannot guarantee that the match is exhaustive.

Indeed, when embedded in the right context, your code throws a match error at runtime:

class Foo {
  val set1 = Set(1,2,3,4,5,67,8)
  val TRUE_BOOLEAN = true
  val FALSE_BOOLEAN = false
  set1.contains(4) match {
    case TRUE_BOOLEAN => println("Element found")
    case FALSE_BOOLEAN => println("Element not found")
  }
}

class Bar extends Foo {
  override val TRUE_BOOLEAN = false
}

new Bar // scala.MatchError: true (of class java.lang.Boolean)

so the warning is correct, and not merely an over-conservative estimate. Since every Scala script is implicitly embedded into some "class-like" wrapper, it also works in Scala scripts in exactly the same way, even if you don't wrap it in a Foo-class.

If you set both variables to final, then constant propagation works properly, and no warning is emitted:

class Foo {
  val set1 = Set(1,2,3,4,5,67,8)
  final val TRUE_BOOLEAN = true
  final val FALSE_BOOLEAN = false
  set1.contains(4) match {
    case TRUE_BOOLEAN => println("Element found")
    case FALSE_BOOLEAN => println("Element not found")
  }
}

compiles just fine, no warnings.

like image 92
Andrey Tyukin Avatar answered Nov 07 '22 21:11

Andrey Tyukin