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.