Reputation: 1679
Why does guarding a case when pattern matching break pattern matching exhaustiveness in Scala?
chris@chris-870Z5E-880Z5E-680Z5E:~/dev/bitcoins-core$ sbt console
[info] Loading project definition from /home/chris/dev/bitcoins-core/project
[info] Set current project to bitcoin-s-core (in build file:/home/chris/dev/bitcoins-core/)
[info] Starting scala interpreter...
[info]
Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_101).
Type in expressions to have them evaluated.
Type :help for more information.
scala> sealed trait A
defined trait A
scala> case class B() extends A
defined class B
scala> case class C() extends A
defined class C
scala> val b : A = B()
b: A = B()
scala> b match { case b : B => () }
<console>:15: warning: match may not be exhaustive.
It would fail on the following input: C()
b match { case b : B => () }
^
scala> b match { case b : B if b.isInstanceOf[B] => () }
scala>
Note on the last line there is no exhaustiveness warning, am I missing something here?
Upvotes: 3
Views: 406
Reputation: 30736
It looks like this is an open issue.
I understand it's disappointing, and it's not very intuitive why we bail out when there are guards, but our key design goal is not to have spurious warnings, as that would undermine their utility while annoying a lot of users.
Upvotes: 3
Reputation: 14825
The compiler is unable to give warning in the second case where isInstanceOf
is used, may be because it thinks user knows the type information of the variable b
.
Scenario 1
scala> b match { case b : B if b.isInstanceOf[B] => () }
scala> def f(b: A) = b match { case b : B if b.isInstanceOf[B] => () }
f: (b: A)Unit
scala> f(C())
scala.MatchError: C() (of class C)
at .f(<console>:14)
... 33 elided
Scenario 2
scala> val b: A = C()
b: C = C()
scala> b match { case b : B if b.isInstanceOf[B] => () }
scala.MatchError: C() (of class C)
... 33 elided
Upvotes: 0