-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing exhaustivity when pattern matching on nested case classes #13003
Comments
Without knowing the code, it seems to me like the "checkable" test isn't correctly considering case classes nested in case classes: private def exhaustivityCheckable(sel: Tree): Boolean = {
// Possible to check everything, but be compatible with scalac by default
def isCheckable(tp: Type): Boolean =
val tpw = tp.widen.dealias
val classSym = tpw.classSymbol
classSym.is(Sealed) ||
tpw.isInstanceOf[OrType] ||
(tpw.isInstanceOf[AndType] && {
val and = tpw.asInstanceOf[AndType]
isCheckable(and.tp1) || isCheckable(and.tp2)
}) ||
tpw.isRef(defn.BooleanClass) ||
classSym.isAllOf(JavaEnumTrait)
val res = !sel.tpe.hasAnnotation(defn.UncheckedAnnot) && {
ctx.settings.YcheckAllPatmat.value
|| isCheckable(sel.tpe)
|| {
val tpw = sel.tpe.widen.dealias
val classSym = tpw.classSymbol
classSym.is(Case) && productSelectorTypes(tpw, sel.srcPos).exists(isCheckable(_))
}
}
debug.println(s"exhaustivity checkable: ${sel.show} = $res")
res
} So looking to shuffling that |
dwijnand
added a commit
to dwijnand/scala3
that referenced
this issue
Jul 8, 2021
Fixes scala#13003, by refixing scala#12485 (PR scala#12488). Part of the issue is that isCheckable behaves differently under -Ycheck-all-patmat and our tests only run under that flag. So for starters I added a test variant where that flag isn't used. I'd like to understand why that flag exists to see if we could remove it from guarding the logic and the tests.
dwijnand
added a commit
to dwijnand/scala3
that referenced
this issue
Jul 9, 2021
Fixes scala#13003, by refixing scala#12485 (PR scala#12488). Part of the issue is that isCheckable behaves differently under -Ycheck-all-patmat and our tests only run under that flag. So for starters I added a test variant where that flag isn't used. I'd like to understand why that flag exists to see if we could remove it from guarding the logic and the tests. Also make sure that any patmat test that throws an exception fails the test...
BarkingBad
pushed a commit
to BarkingBad/dotty
that referenced
this issue
Jul 23, 2021
Fixes scala#13003, by refixing scala#12485 (PR scala#12488). Part of the issue is that isCheckable behaves differently under -Ycheck-all-patmat and our tests only run under that flag. So for starters I added a test variant where that flag isn't used. I'd like to understand why that flag exists to see if we could remove it from guarding the logic and the tests. Also make sure that any patmat test that throws an exception fails the test...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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…
…the compiler only emits warnings about non-exhaustive matches for
matchTwo()
,matchOO()
, andmatchOOO()
but not formatchOneTwo()
– unless compiler option-Ycheck-all-patmat
is given.Output
Without option
-Ycheck-all-patmat
the output is:Adding compiler option
-Ycheck-all-patmat
causes the missing case to be detected:However, from the description of the compiler option:
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
.The text was updated successfully, but these errors were encountered: