I don’t get why a match type is not always reduced. Match types should help to eliminate illegal arguments on compilation. But as it turns out it does not always reduce in full.
Take this silly example:
sealed trait AB
case class A() extends AB
case class B() extends AB
type OnlyA[X] = X match
case A => A
def onlyA[X <: Matchable](x: X): OnlyA[X] = x match
case a: A => a
val isA: OnlyA[A] = onlyA(A())
val isB: OnlyA[B] = onlyA(B()) // fails as expected
val isAorB: OnlyA[AB] = onlyA(B(): AB) // should fail? does compile, no reduction triggered?
val ev = summon[OnlyA[AB] =:= A] // show a reduce failure as expected
isB
is correctly rejected by the compiler but isAorB
should fail because there is no path and it cannot prove it to be disjoint because it could be AB.A
.
Strangely when actively using the type in an equality check, it does try to reduce it and fails as expected.
What do I get wrong or is this a compiler bug?