1

The scala compiler seems to give false type-errors for statements with multiple lower bounds.

Given class Foo with the method g using a lower bound for A and B

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

from https://stackoverflow.com/a/6124549, and classes X, Y <: X and Z <: 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"}

the following code works fine, as expected:

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

Surprisingly,

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

does not! (tested in Scala 2.12.7, 2.12.8, 2.13.0-M5, but it does work as expected in Dotty)

It yields error: value a is not a member of type parameter T.

Is this a bug in the compiler or is there a specific reason, why I cannot call a on new Foo(Y,Z).g.head?

y gets the type X, so the compiler can obviously figure out that new Foo(Y,Z).g.head is of type X, and I do not get, why assigning it to a new value and calling the method on that helps the type-checker. Also, I think, explicitly casting to X should not change anything, but it does.

Try online!

anselm
  • 76
  • 4

0 Answers0