-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Pattern matching on unchecked generic types (with isInstanceOf guard) does not work correctly #14705
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
I think the Scala 3 behavior is correct, but on the
with the correct pun on fruit. |
Some type tests are elided or replaced with non null-checks if we can show that the expression's type is a subtype of the test type. But that can be done safely only if the expression's type does not come from an `@unchecked` cast, inserted by pattern matching or the user. Fixes scala#14705
Good afternoon, I'd like to oppose to the notion that Scala 3 behavior is the correct one in this case. For all the time I spent with Scala my understanding of @unchecked in pattern matches, especially the ones on a generic datatype with a provided type parameter, was that I provide a type parameter I'd like to get an implicit cast for and I am aware that I can't match on a generic type, because it's erased. Therefore I have to provide another check to make sure that this implicit cast is a correct one and that guard relying on The warning emitted in Scala 2 informed about exactly that:
This new behavior puts this whole assumption and learned experience on its head. Now the @unchecked somehow mean "in this pattern match I am sure that the first thing you are going to match on is definitely tl;dr: folks depended on this behavior of scala 2 to get free implicit casts and used @unchecked to suppress warning because they knew that they are going off the rails and introduced a proper check in a guard. This change breaks existing code and understanding of erasure in patmat. Source: I work with @liosedhel, we have encountered this as a bug leading to ClassCastExceptions on prod in a system migrated to Scala 3. |
I think the PR respects the extended comment. I think that is OK if folks want to "de-optimize" the I stand by my pun, of course. The spec should clarify that if I say But that is not what the previous comment asks. So the spec must clarify that Full disclosure, I don't use the idiom that warns, so I don't know what is most useful. |
No, it means that "in this pattern March, if the thing you are going to match is a The meaning was the same in Scala 2. The difference is only that Scala 2 did not use the knowledge to constant fold the Now, there's a case to be made that such a constant fold should emit a warning as a tautological test. |
Some type tests are elided or replaced with non null-checks if we can show that the expression's type is a subtype of the test type. But that can be done safely only if the expression's type does not come from an `@unchecked` cast, inserted by pattern matching or the user. Fixes scala#14705
@lbialy has a point. What would be an alternative to case appleBox: Box[Apple] @unchecked if appleBox.fruit.isInstanceOf[Apple] => if we rejected the Note also that we do in general flag redundant So the choice seems to be between two alternatives:
(2) poses backwards compatibility problems. First, a warning is a weak message to signal a change in runtime behavior. Second, we are still lacking a good replacement for such code. That's why #14709 implements (1). |
If it is only "if the scrutinee has an case appleBox: Box[Apple] @unchecked if appleBox.fruit.isInstanceOf[Apple] =>
1
case _ =>
2 is not equivalent to case appleBox: Box[Apple] @unchecked =>
if appleBox.fruit.isInstanceOf[Apple] then
1
else
2
case _ =>
2 anymore. Is that acceptable? In other words, it's not really a question of optimizing or not. It's a question of changing the specified semantics of types inside the guard of a pattern match that has |
In fact the two snippets are still equivalent. The scrutinee has an @unchecked type in both. |
Another approach would be to never optimize |
Uh oh!
There was an error while loading. Please reload this page.
Compiler version
scala 3.1.1
Minimized code
Output
Expectation
Only Box with Apple inside should be matched as "apple". It works for 2.13.x scala version. It can be workarounded with
The text was updated successfully, but these errors were encountered: