Pattern matching on unchecked generic types (with isInstanceOf guard) does not work correctly
See original GitHub issueCompiler version
scala 3.1.1
Minimized code
trait Fruit
case class Apple() extends Fruit
case class Orange() extends Fruit
case class Box[C](fruit: C) extends Fruit
val apple = Box(fruit = Apple())
val orange = Box(fruit = Orange())
val result = List(apple, orange).map {
case appleBox: Box[Apple] @unchecked if appleBox.fruit.isInstanceOf[Apple] => //contains apple
"apple"
case _ =>
"orange"
}
assert(result == List("apple", "orange"))
Output
result == List("apple", "apple")
Expectation
Only Box with Apple inside should be matched as “apple”. It works for 2.13.x scala version. It can be workarounded with
case appleBox: Box[_] @unchecked if appleBox.fruit.isInstanceOf[Apple] =>
val a = appleBox.asInstanceOf[Box[Apple]]
Issue Analytics
- State:
- Created 2 years ago
- Comments:8 (5 by maintainers)
Top Results From Across the Web
How do I get around type erasure on Scala? Or, why can't I get ...
Scala was defined with Type Erasure because the Java Virtual Machine (JVM), unlike Java, did not get generics. This means that, at run...
Read more >Type Erasure in Scala - Sid Shanker's Blog
We now pattern match on the typeOf[T] , instead of on Thing itself. This works correctly, and now we can actually distinguish between...
Read more >Ways to pattern match generic types in Scala - gists · GitHub
In this article, I demonstrate a few solutions that can be used when pattern matching against generic types. First, I'll demonstrate two ways...
Read more >Overcoming type erasure in Scala - Medium
We know that pattern matching is able to figure out the type of a given object without problems by deconstructing it.
Read more >4. Pattern Matching - Programming Scala, 3rd Edition [Book]
The intent is that pattern matching can only occur on values of type Matchable , not Any . Since almost all types are...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I think the Scala 3 behavior is correct, but on the
isInstanceOf
, it should warn,with the correct pun on fruit.
If it is only “if the scrutinee has an
@unchecked
type”, it means thatis not equivalent to
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
@unchecked
. Do you want to put that in the spec? We would have to say something like, in the guard of a case, we don’t trust the types beyond their erasure. What does that even mean in terms of type system? Can we still remotely reason about soundness in that situation? What about GADT soundness in this context? There is so much we don’t know once we “relax” run-time semantics like that. Previously, I could explain the meaning of@unchecked
in one sentenced (see my previous comment); now I need to make sweeping changes to my understanding of the type system.