Closed
Description
Although A & B
and B & A
are claimed to be the same type, the are not the same for overriding and overloading.
It seems to be "caused" by erasue, which erases A & B
to A
and B & A
to B
.
Overriding
trait A
trait B
class Base{
def m(ab: A&B) = ab
}
class Derived extends Base{
override def m(ab: B&A) = ab // unexpected error
}
Output:
8 | override def m(ab: B&A) = ab // unexpected error
| ^
| error overriding method m in class Base of type (ab: A & B): A & B;
| method m of type (ab: B & A): A & B has incompatible type
On the other hand, if the override
is omitted, an error is correctly issued.
class Derived2 extends Base{
def m(ab: B&A)=ab // OK - "needs override" error when expected
}
Also, when the first type in the intersection is the same (therefore erased type is the same), overriding works as expected:
trait C
class Base3{
def m(abc: A&B&C) = abc
}
class Derived3 extends Base3{
override def m(abc: A&C&B) = abc // OK - no error
}
Overloading
Similarly, overloading is allowed when the first type differs.
class Overload{
def m(ab: A&B) = ab
def m(ab: B&A) = ab // No error when expected
}
On the other hand, such methods cannot be called, as expected:
object Caller{
Overload.m(new A with B) // OK - "ambiguous overload" error when expected
}
That seems to be the same behavior as with scalac.