class A
class B
def test(x: (A, B) | (B, A)) = x match {
case (u: A, v) => (u, v)
case (u: B, v) => (v, u)
}
https://scastie.scala-lang.org/ifiEqLPETBq2eruEbFXfFQ
match may not be exhaustive.
It would fail on pattern case: Tuple2(_, _)
Moreover, the type inferred for v is always Object, whereas it could be more precise here.
No warning, and more precise types.
Might have the same root cause as https://github.com/lampepfl/dotty/issues/8681 ?
The warning is fixed in #8698. This bug is caused by a different problem from #8681. The warning in the latter is issued during erasure.
However, it seems complex to give a more precise type to v. Any ideas @smarter ?
However, it seems complex to give a more precise type to v. Any ideas @smarter ?
I had a quick look and it doesn't seem easy yeah, there's various places which assume that the unapply method type is fully inferred before typing the unapply arguments, I think that part of the issue should be considered a feature request and not a bug.
@smarter fair enough, as long as the fully-annotated version works:
def test(x: (A, B) | (B, A)) = x match {
case (u: A, v: B) => (u, v)
case (u: B, v: A) => (v, u)
}
(@liufengyun it would be good to test that code too.)
@LPTK The exhaustivity check can handle the code above (thanks for the test), but in a later phase there's a warning saying:
the type test for A cannot be checked at runtime
So, you may need a ClassTag for A and B.
@liufengyun isn't that warning spurious? A and B are classes, not type parameters.
@LPTK I adapted the test https://github.com/lampepfl/dotty/pull/8698/commits/030249b183601fb80c35bdf98b1069b4e6120579
Most helpful comment
I had a quick look and it doesn't seem easy yeah, there's various places which assume that the unapply method type is fully inferred before typing the unapply arguments, I think that part of the issue should be considered a feature request and not a bug.