How can an object in Scala be cast to the intersection of its own type and any unrelated trait?

StackOverflow https://stackoverflow.com/questions/23108978

  •  04-07-2023
  •  | 
  •  

Frage

Consider the following:

trait Foo { def bar: Any }

Now, 3 and X don't even have a method bar yet this compiles:

val a = 3.asInstanceOf[Int with Foo]

object X
val b = X.asInstanceOf[X.type with Foo]

This code, when compiled and run (on Scala 2.10.3), produces no error. However, the following will compile cleanly but will produce a ClassCastException at runtime:

val a1 = a.asInstanceOf[Foo]
val b1 = b.asInstanceOf[Foo]

How can this be? I can almost accept the fact that no static analysis/checking is performed on explicit casts, and they're discouraged and usually unneeded anyway—although I do think Scala could emit a warning about a definitely incorrect type cast given that there is no way object X can ever have the trait Foo, nor an integer—however I can't easily accept the fact that an integer can be cast at runtime to an intersection type containing a completely irrelevant and non-empty trait.

War es hilfreich?

Lösung

The problem is that JVM doesn't support intersection types, so there is no obvious runtime equivalent to asInstanceOf[Int with Foo]. This is basically the same issue as asInstanceOf[T], where T is a generic parameter (both in Scala and equivalent Java): you also have the cast which appears to succeed at runtime but actually inserts casts in later code which uses methods of T.

One possibility would be to compile the cast to Int with Foo as two casts to Int and to Foo, but this doesn't quite work in general (e.g. when there is no runtime cast to Foo itself, or when the value is passed to methods which take Int with Foo).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top