Chris Stewart
Chris Stewart

Reputation: 1679

Scala pattern matching guard breaks pattern matching exhaustiveness?

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

Answers (2)

Chris Martin
Chris Martin

Reputation: 30736

It looks like this is an open issue.

A comment by Adriaan Moors:

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

Nagarjuna Pamu
Nagarjuna Pamu

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

Related Questions