Closed
Description
Minimized code
@main def test: Unit = {
class C { type T1; type T2 }
def pmatch(s: C): s.T2 = s match {
case p: (C { type T1 = Int; type T2 >: T1 } & s.type) =>
(3: p.T1): p.T2
case p: (C { type T1 = String; type T2 >: T1 } & s.type) =>
("this branch should be matched": p.T1): p.T2
}
// ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String
val x = pmatch(new C { type T1 = String; type T2 = String })
}
Output
Click to expand
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at main$package$.test(main.scala:12)
at test.main(main.scala:1)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sbt.Run.invokeMain(Run.scala:115)
at sbt.Run.execute$1(Run.scala:79)
at sbt.Run.$anonfun$runWithLoader$4(Run.scala:92)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
at sbt.util.InterfaceUtil$$anon$1.get(InterfaceUtil.scala:10)
at sbt.TrapExit$App.run(TrapExit.scala:257)
at java.lang.Thread.run(Thread.java:748)
Expectation
We could expect the second branch to be matched, but due to erasure, I do not think it is possible.
I believe issuing a warning specifying that such a runtime check cannot be performed could be a consideration. I also think that (3: p.T1): p.T2
should be rejected since we cannot be certain that we have { type T1 = Int; type T2 >: T1 }
(similarly for the second match branch).