Reputation: 41939
Let's say that I have a trait, Parent, with one child, Child.
scala> sealed trait Parent
defined trait Parent
scala> case object Boy extends Parent
defined module Boy
I write a function that pattern matches on the sealed trait. My f
function is total since there's only a single Parent
instance.
scala> def f(p: Parent): Boolean = p match {
| case Boy => true
| }
f: (p: Parent)Boolean
Then, 2 months later, I decide to add a Girl
child of Parent
.
scala> case object Girl extends Parent
defined module Girl
And then re-write the f
method since we're using REPL.
scala> def f(p: Parent): Boolean = p match {
| case Boy => true
| }
<console>:10: warning: match may not be exhaustive.
It would fail on the following input: Girl
def f(p: Parent): Boolean = p match {
^
f: (p: Parent)Boolean
If I were to encounter a non-exhaustive match, then I'd get a compile-time warning (as we see here).
However, how can I make the compilation fail on a non-exhaustive match?
Upvotes: 24
Views: 4992
Reputation: 1580
A compiler flag for Sbt and Scala 3 :
scalacOptions += "-Ycheck-all-patmat"
Many flags for Scala 2 do not work with Scala 3.
more on Scala 3 compiler flags
Upvotes: 1
Reputation: 101
Since scalac 2.13.2 there's a fairly granular control of warnings. To get what OP asks:
scalacOptions += "-Wconf:cat=other-match-analysis:error"
Upvotes: 10
Reputation: 42045
You can add -Xfatal-warnings
to Scalac's options. That way any warning will be treated as an error.
In sbt, you can achieve that with:
scalacOptions += "-Xfatal-warnings"
Upvotes: 13
Reputation: 1849
Perhaps you could put in a default case to catch post-defined elements and bind it to a partial function which you can manage separately. Then the partial will act as a "default handler".
sealed trait Animal
case class Dog(name: String) extends Animal
case class Cat(name: String) extends Animal
val t: Animal = Dog("fido")
// updates when the trait updates
val partial = PartialFunction[Animal, Unit] {
case Dog(_) => println("default dog")
case Cat(_) => println("default cat")
case _ => throw new RuntimeException("Broken")
}
// matches that may be out of date refer to it
t match {
case Dog(_) => println("specific dog")
case t => partial(t)
}
Or perhaps you can just use PartialFunctions all the way through and chain them together.
Upvotes: -7