9

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.

Jesper
  • 202,709
  • 46
  • 318
  • 350

2 Answers2

13

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.

axel22
  • 32,045
  • 9
  • 125
  • 137
  • Ok, so if I leave out the type annotation, in the second match it tries to match `Tuple2[_, _]` instead of `Tuple2[Int, Int]` and it doesn't need to check the erased type parameters. So it's an unfortunate side-effect of the special syntax for tuples. – Jesper Mar 07 '11 at 22:06
5

I think the short answer to your question is:

class Example {
  val (x: Int, y: Int) = (1, 2)
}

because (Int, Int) is not a type, while (x: Int, y: Int) is a valid pattern expression.

Marcello Nuccio
  • 3,901
  • 2
  • 28
  • 28