Description
When pattern matching on a nested case class pattern like, case One(Two(Some(...)))
the Scala 3 compiler does not detect the match as being non-exhaustive – unless option -Ycheck-all-patmat
is given.
Compiler version
I have tested on compiler version 3.0.2-RC1-bin-20210701-9f97b0b-NIGHTLY (as well as on 3.0.0 where even more cases go undetected.)
Minimized code
Given this code…
case class One(two: Two)
case class Two(o: Option[Int])
def matchOneTwo(one: One) = one match
case One(Two(Some(i))) => "match!"
def matchTwo(two: Two) = two match
case Two(Some(i)) => "match!"
def matchOO(oo: Option[Option[Int]]) = oo match
case Some(Some(i)) => "match!"
def matchOOO(ooo: Option[Option[Option[Int]]]) = ooo match
case Some(Some(Some(i))) => "match!"
…the compiler only emits warnings about non-exhaustive matches for matchTwo()
, matchOO()
, and matchOOO()
but not for matchOneTwo()
– unless compiler option -Ycheck-all-patmat
is given.
Output
Without option -Ycheck-all-patmat
the output is:
-- [E029] Pattern Match Exhaustivity Warning: /path/to/Example.scala:7:25
7 |def matchTwo(two: Two) = two match
| ^^^
| match may not be exhaustive.
|
| It would fail on pattern case: Two(None)
-- [E029] Pattern Match Exhaustivity Warning: /path/to/Example.scala:10:39
10 |def matchOO(oo: Option[Option[Int]]) = oo match
| ^^
| match may not be exhaustive.
|
| It would fail on pattern case: None, Some(None)
-- [E029] Pattern Match Exhaustivity Warning: /path/to/Example.scala:13:49
13 |def matchOOO(ooo: Option[Option[Option[Int]]]) = ooo match
| ^^^
| match may not be exhaustive.
|
| It would fail on pattern case: None, Some(None), Some(Some(None))
three warnings found
three warnings found
Adding compiler option -Ycheck-all-patmat
causes the missing case to be detected:
4 |def matchOneTwo(one: One) = one match
| ^^^
| match may not be exhaustive.
|
| It would fail on pattern case: One(Two(None))
-- [E029] Pattern Match Exhaustivity Warning: /path/to/Example.scala:7:25
However, from the description of the compiler option:
-Ycheck-all-patmat Check exhaustivity and redundancy of all pattern
matching (used for testing the algorithm).
I would not expect this option to be one to use “in production” – I might be wrong here.
Expectation
I would expect the compiler to detect all four cases without the use of compiler option -Ycheck-all-patmat
.