question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Pattern matching on unchecked generic types (with isInstanceOf guard) does not work correctly

See original GitHub issue

Compiler 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:closed
  • Created 2 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
som-snyttcommented, Mar 17, 2022

I think the Scala 3 behavior is correct, but on the isInstanceOf, it should warn,

fruitless type test

with the correct pun on fruit.

1reaction
sjrdcommented, Mar 19, 2022
  1. Behave like Scala 2 and don’t optimize isInstanceOf checks, at least not if the scrutinee has an @unchecked type.

If it is only “if the scrutinee has an @unchecked type”, it means that

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 @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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found