Anyone know why these generate unchecked-type warnings...
def anyMap(a: Any): Unit = a match {
case _: Map[Any, Any] =>
}
//warning: non-variable type argument Any in type pattern scala.collection.immutable.Map[Any,Any] (the underlying of Map[Any,Any]) is unchecked since it is eliminated by erasure
def intList(a: Any): Unit = a match {
case _: List[Int] =>
}
//warning: non-variable type argument Int in type pattern List[Int] (the underlying of List[Int]) is unchecked since it is eliminated by erasure
...but this does not?
def anyList(a: Any): Unit = a match {
case _: List[Any] =>
}
//[crickets]
Mostly just curious. Thanks
Scala can verify that the type of something satisfies List[Any]
simply by checking that it is a List
. This is because the list type is covariant in its first argument, so even if you pass it a List[Int]
or a List[Double]
, those are still subclasses are List[Any]
, so all the compiler has to do is check List
, which it can do at runtime. The type erasure doesn't affect its ability to do this.
Checking if something is a List[Int]
would require knowing the actual type of the elements, which is erased at runtime, and Scala can't do the same trick with Map[Any, Any]
since the map type is invariant in its first argument. So while Map[Any, Int]
is a subclass of Map[Any, Any]
, Map[Int, Any]
is not. Thus, Scala would have to be able to check the type of the first argument, which it cannot do at runtime.
More about variance can be found in the docs.