scala编译器似乎为具有多个下限的语句提供了错误的类型错误 .

给定 Foo 类,方法 g 使用 AB 的下限

class Foo[A, B](a: A, b: B) {
  def g[T, A1 >: A <: T, B1 >: B <: T] = List[T](a: A1, b: B1)
}

来自https://stackoverflow.com/a/6124549,以及类 XY <: XZ <: X

abstract class X {def a: String}
object Y extends X {def a = "this is Y"}
object Z extends X {def a = "this is Z"}

以下代码正常工作,如预期:

Y.a
new Foo(Y,Z).g
new Foo(Y,Z).g.head // instance of Y, type X
new Foo(Y,Z).g.head.isInstanceOf[X] // true
new Foo(Y,Z).g.head.asInstanceOf[X].a
new Foo(Y,Z).g[X,Y.type,Z.type].head.a
new Foo(Y,Z).g[X,X,X].head.a
val y = new Foo(Y,Z).g.head
y.a

出奇,

new Foo(Y,Z).g.head.a

not ! (在Scala 2.12.7,2.12.8,2.13.0-M5中测试,但它确实在Dotty中按预期工作)

它产生 error: value a is not a member of type parameter T .

这是编译器中的错误还是有特定原因,为什么a不能在 new Foo(Y,Z).g.head 上调用 a

y 获取类型 X ,因此编译器可以明显地发现 new Foo(Y,Z).g.head 的类型为 X ,并且我没有得到,为什么将其分配给新值并调用该方法有助于类型检查器 . 另外,我认为,明确地转换为 X 不应该改变任何东西,但确实如此 .

Try online!