I have the following example code:
trait Recurse[T <: Recurse[T]] {
def method = "This is a method on recurse"
}
class Foo extends Recurse[Foo] {
override def toString = "This is a foo"
}
object Example {
def generate: Recurse[_ /*<: Recurse[_]*/] = new Foo()
def main(args: Array[String]) {
val foo = generate
foo match {
case m: Foo => println("match: " + m)
case _ => println("baa")
}
println(foo.method)
}
}
This code compiles and runs correctly on 2.9.x (outputs "match: This is a foo" followed by "This is a method on recurse"), but it does not work on 2.10.2. Instead I get the compile-time error: type arguments [_$1] do not conform to trait Recurse's type parameter bounds [T <: Recurse[T]]
What is interesting about this is that the problem occurs only in the pattern matcher. If I remove the match block, the code compiles and the code outputs "This is a method on recurse".
Even more interesting is that the pattern match will still fail to compile even if the only thing in it is the default case! The compiler simply will not accept an object with a recursive existential type for a pattern match. However, if value of foo is specified explicitly ("val foo = new Foo()"), or if the type parameter is not recursive, then the code will compile even on 2.10.
What is going on here? Why does this break pattern matching even if the type parameter is not involved in the match in any way? Is there any way to rewrite this in a 2.10-compatible way?