2

In Scala 2.10.0-M4

object X
def f(e: Either[Int, X.type]) = e match {
  case Left(i) => i
  case Right(X) => 0
}

gives:

warning: match may not be exhaustive.
It would fail on the following input: Right(<not X>)

Is this correct? Surely the match is in fact exhaustive.

(Meanwhile, back in Scala 2.9.X we get

error: pattern type is incompatible with expected type;
 found   : object X
 required: X.type
           case Right(X) => 0

which presumably was a bug.)

Scott Morrison
  • 3,100
  • 24
  • 39
  • It seems like the type checker doesn't distinguish singleton types from normal types in this case. Anyways I guess you know that matching on Right(_) would be safe too, since Right can only be of type X.type, right? – Kaito Jun 23 '12 at 01:57
  • Yes, this was my 'workaround'. – Scott Morrison Jun 23 '12 at 05:12
  • Open a bug report. It might not be a bug, but, then again, it might. Exhaustiveness check is very recent code on Scala 2.10, and this is just the sort of feedback I imagine Adriaan would like. – Daniel C. Sobral Jun 23 '12 at 16:46
  • Reported as https://issues.scala-lang.org/browse/SI-5968 – Scott Morrison Jun 23 '12 at 18:31

2 Answers2

5

Sadly, there are two values which inhabit X.type. One is the obvious one, X, and the other of course is null. Thus your pattern has missed a case :(

mergeconflict
  • 8,156
  • 34
  • 63
  • 1
    While correct, this is something the type checker usually ignores, as you'd have to account for it every time. He could match on Right(_) and still get a match error if null is passed, this time with no warning from the compiler. – Kaito Jun 23 '12 at 02:06
  • Indeed, the compiler doesn't care that there is no `case null => ...` since it ignores that possibility for sealed classes. But evidently (and I'm not positive about this!) when the compiler gets into exhaustiveness-checking mode, it checks all sub-patterns as well. I guess you could call that a bug :/ – mergeconflict Jun 23 '12 at 02:13
  • 1
    In my tests it throws a match error when passing Right(null) as well, even if you don't try to access the contents. Using non sealed classes gives the same behavior, no warnings and a match error. It seems normal to me that the compiler wouldn't warn me about that. GHC doesn't warn about bottom either. – Kaito Jun 23 '12 at 02:39
  • 1
    Right, that's why I'm suggesting you could probably consider this a compiler bug. Or maybe a spec bug, although I haven't looked at the spec. I'm not saying the reason scalac is warning about non-exhaustive patterns is necessarily a *good* reason ;) – mergeconflict Jun 23 '12 at 03:40
2

And it's been patched, c.f. https://github.com/retronym/scala/compare/ticket/5968.

Scott Morrison
  • 3,100
  • 24
  • 39