2

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?

4

2 回答 2

2

这是SI-7716,已在 2.10.3 和 2.11 中修复。

于 2013-10-02T15:38:29.340 回答
1

我相信这是 Scala 编译器的回归。为什么不归档呢

于 2013-09-01T12:51:33.200 回答