According to the scala specification, the extractor built by case classes is the following (scala specification §5.3.2):
def unapply[tps](x: c[tps]) =
if (x eq null) scala.None
else scala.Some(x.xs11, ..., x.xs1k)
For implementation reasons, I want to be able to mimic the behavior of this extractor on a non-case class. However, my implementation fails to reproduce the same behavior.
Here is an example of the difference i have:
trait A
sealed trait B[X <: A]{ val x: X }
case class C[X <: A](x: X) extends B[X]
class D[X <: A](val x: X) extends B[X]
object D {
def unapply[X <: A](d: D[X]): Option[X] =
if (d eq None) None
else Some(d.x)
}
def ext[X <: A](b: B[X]) = b match {
case C(x) => Some(x)
case D(x) => Some(x)
case _ => None
}
I have the following warning :
<console>:37: warning: non variable type-argument X in type pattern D[X] is unchecked since it is eliminated by erasure
case D(x) => Some(x)
Notice the warning occurs only in the D
case, not in the case-class textractor case.
Do you have any idea about the cause of the warning / about what I should do to avoid this warning ?
Note: If you want to test it in REPL, the easiest way is:
To activate unchecked warning
scala> :power
scala> settings.unchecked.value = true
To copy above code in paste mode:
scala> :paste
[copy/paste]
[ctrl + D]
Edit: As Antoras mentioned it should be a compiler bug, maybe the scala version could be useful: scala 2.9.0.1 (after a quick test, still there in scala 2.9.1RC2)
This seems to be a compiler bug. I have analyzed the output of the compiler AST (with
fsc -Xprint:typer <name_of_file>.scala
). It interprets both as the same:The method signature of both methods unapply are identical.
Furthermore the code works fine (as expected due to identical methods):