effekt icon indicating copy to clipboard operation
effekt copied to clipboard

Misleading error message on a nested non-exhaustive pattern match

Open jiribenes opened this issue 1 month ago • 1 comments

Problem

The compiler reports a somewhat misleading error message which tells me that "a case for Cons is missing", but it actually means that the Cons(_, Cons(_, _)) case is missing: Screenshot 2024-05-22 at 22 01 23

Potential solution

It would be nicer to use the full scrutinee Trace when reporting the error to actually compute which case we're missing. Here we actually do pass it, but then we don't use it :( https://github.com/effekt-lang/effekt/blob/2739c4791191fc18aab554d443ed3fa81d556f25/effekt/shared/src/main/scala/effekt/typer/ExhaustivityChecker.scala#L207

I went ahead and tried to debug-print the scrutinee in the error message which leads me to believe that it does contain the necessary information:

Non exhaustive pattern matching, missing case for Cons at Child(Cons,tail,Root(Var(IdRef(List(),list))))

I don't know how we should represent the missing case though, especially if we want to keep the other similar errors in sync. Maybe the error messages could already try to format it in the style of the source language like:

Non exhaustive pattern matching, missing case for Nil()
Non exhaustive pattern matching, missing case for Cons(_, _)
Non exhaustive pattern matching, missing case for Cons(_, Cons(_, _))

Nitpick

Should we keep the underscores or should we actually provide names based on the accessors (see below)?

Non exhaustive pattern matching, missing case for Nil()
Non exhaustive pattern matching, missing case for Cons(head, tail)
Non exhaustive pattern matching, missing case for Cons(head, Cons(head1, tail))

Details

I originally noticed this in a much larger, more complex pattern match, but I minified it for the issue itself. Here's the minified repro:

def test(lst: List[Int]) = lst match {
  case Nil() => 42
  case Cons(x, Nil()) => 100
}

jiribenes avatar May 22 '24 20:05 jiribenes