Dotty: Spurious exhaustiveness warning for union of tuple types

Created on 7 Apr 2020  路  7Comments  路  Source: lampepfl/dotty

Minimized code

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

Output

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.

Expectation

No warning, and more precise types.

pattern-matching bug fix available

Most helpful comment

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.

All 7 comments

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.

Was this page helpful?
0 / 5 - 0 ratings