Closed
Description
Originally reported by @szeiger at scala/bug#13090
scala> sealed trait A[T] { def x: T }
| final case class B(x: String) extends A[String]
| final case class C(x: Int) extends A[Int]
scala> def f[T](a: A[T]): T = a match { case B(_) | C(_) => "plop" }
scala> f(C(1)) + 1
java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap')
at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:99)
It seems only the constraints from the first pattern are applied, so T = String
when typing the case body.
The bug report initially asked if it's possible to support this case:
scala> def f[T](a: A[T]): T = a match {
| case B(_) | C(_) => a match { case C(_) => 42 }
| }
-- [E007] Type Mismatch Error: -------------------------------------------------
2 | case B(_) | C(_) => a match { case C(_) => 42 }
| ^^
| Found: (42 : Int)
| Required: T
|
| where: T is a type in method f which is an alias of String