Have a look at this Scala class:
class Example {
val (x, y): (Int, Int) = (1, 2)
}
Compiling this results in a warning:
Example.scala:2: warning: non variable type-argument Int in type pattern
(Int, Int) is unchecked since it is eliminated by erasure
val (x, y): (Int, Int) = (1, 2)
^
Removing the explicit type annotation gets rid of this warning:
class Example {
val (x, y) = (1, 2)
}
Why do I get the warning and why does removing the explicit type annotation get rid of it? As far as I can see nothing really changes, x
and y
are still of type Int
without the type annotation.
You could rewrite your example to:
class Example {
val Tuple2(x, y): Tuple2[Int, Int] = Tuple2(1, 2)
}
This pattern match actually consists of 2 matches - it now says: take the right hand side object of type Tuple2[Int, Int]
and call the method unapply[Int, Int]
on the Tuple2
companion object. The unapply[Int, Int]
will then verify that the object really has the type Tuple2
, and its result value will be used to bind values to variables x
and y
.
After that, this pattern match contains : Tuple2[Int, Int]
, so it tries to do an isInstanceOf[Tuple2[Int, Int]]
check dynamically to see if the object additionally has the type Tuple2[Int, Int]
. However, generic type information is erased at runtime, so the compiler warns that it cannot actually produce code which verifies that the object is instantiated for type parameters [Int, Int]
.
In the same way, in the following pattern match:
val a: AnyRef = (1, 2)
a match {
case t2: Tuple[Int, Int] =>
}
you would get a similar warning.