-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Unions of Singletons unreachable literals not being checked in pattern match. #12805
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
Comments
EDIT: Never mind. Looks like this is in fact something the union type implementation supports. The following works:
|
It seems that exclusivity checks does not pick up a case where additional singletons are provided.
|
you don't even need to bring a union into it: scala> def foo(a: 1) = a match { case 1 => 1; case 2 => 2 }
def foo(a: 1): Int
scala> def foo(a: 1) = a match { case 1 => 1; case _ => 2 }
def foo(a: 1): Int neither warns, but both should warn I wondered if this was a degenerate case of the union case, but maybe it's actually an orthogonal bug on a different theme (namely, inappropriate widening of the scrutinee type); on that theme, see scala/bug#11603 / scala/scala#9209, which Dale fixed in Scala 2 in 2020 UPDATE: I have now opened #13342 on this. |
in // `covered == Empty` may happen for primitive types with auto-conversion
// see tests/patmat/reader.scala tests/patmat/byte.scala
if (covered == Empty && !isNullLit(pat)) covered = curr commenting this line out causes at least one Krzysztof's test cases to progress, so this may be the key piece of code. it was added by Fengyun in #4253 That piece of code seems to be about making a match such as in the Scala 2 spec, SLS 8.1.4 says:
As far as I can tell, there was an oversight here where "must conform" should say "must weakly conform", and that's why it's legal to match with a But in Scala 3, we don't have weak conformance anymore. So there needs to be some other justification for considering such a match to be reachable. The justification is provided by https://docs.scala-lang.org/scala3/reference/dropped-features/weak-conformance-spec.html , which says that such conversions as Perhaps we can find a more targeted way to support auto-conversion that doesn't negatively impact other scenarios. |
Also wondering why we can't make this an error instead of just warning. Imo the compiler should be guiding the user why its not possible not allow holes like this through? |
Dead code, such as unreachable cases or even just unused imports, can be misleading and so are worth linting. But by themselves they aren't hazardous, and stopping compilation might prove very annoying. |
I think warnings dead code and unused imports are fine and think it forms validation compilation, but for unreachable cases, invalid patterns it seems odd to have it as a warning, at least by default. Same with match types. type M[X <: String] = X match
case "SA" => Int
case 12 => String If some invalid construct compiles, most likely someone will use it in their codebase. What about by default it being an error and ability to use it as warning. I have some warnings in my codebase like obsolete that I tend to ignore, but usually cases like this slips through as well. |
When configurable warnings gets merged (soon hopefully) then you should be able to promote a reachability warning into a reachability error. Match types are different though, and I'm not too sure yet how much more worrisome unreachable cases are there. Same with in-exhaustive match types... 🤔 |
Note that that documentation doesn't actually directly cover this. It applies to numeric expressions, not numeric patterns. It does mention pattern matching, but that language is about the right-hand-sides of matches (expressions), not the left-hand sides (patterns). We're doing something similar to numeric patterns, and in the context of reachability-and-exhaustiveness analysis only. Ultimately the justification for this isn't the doc I cited, the justification is that numeric types are spec'ed as comparing equal at runtime, despite being unrelated by subtyping. (Regardless, in the hypothetical future Scala 3 spec, in the equivalent of SLS 8.1.4, maybe the "The type of L must conform to the expected type of the pattern" sentence should simply be omitted? It seems like warnings/linting territory to me, rather than something that needs to be spec'ed with an unequivocal word such as "must". 🤷 ) |
Dale and I attempted a fix on the draft PR #13290, but our efforts may have stalled; see our recent remarks there. |
The pattern match on the lhs side doesn't exhaustively check if the pattern is of valid type for singletons of union.
In this example both
240
and4H
are not a valid subtype of bothTimeframeN
andTimeframe
respectively, but compiler appears to compile without reporting type mismatch errors. It appears as if union type is widen'ed prematurely.Compiler version
3.0.1-RC1
Minimized code
Output
No errors on compilation
Expectation
Type mismatch errors. Hypothetical sample:
Note that this doesn't happen if the returning subtype is invalid. In such cases, compiler reports a type mismatch error correctly.
The text was updated successfully, but these errors were encountered: