scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

Incorrect "match may not be exhaustive" warning matching on Seq with `-Xlint:strict-unsealed-patmat` #12754

Closed timw closed 1 year ago

timw commented 1 year ago

Reproduction steps

Scala version: 2.13.10

Compile with -Xlint:strict-unsealed-patmat

object SeqMatchTest {

  def main(args: Array[String]): Unit = {

    def test(seq: Seq[_]): Unit = seq match {
      case Seq()  => println(s"$seq is empty")
      case Seq(_, _ @_*) => println(s"$seq has one or more elements")
//      case _      => println(s"$seq is never matched")
    }

    test(Seq())
    test(Seq(1))
    test(Seq(1, 2))
    test(Seq(1, 2, 3))
  }
}

Problem

When compiled with no lints, the above code compiles with no warnings and runs correctly. When compiled with -Xlint:strict-unsealed-patmat it produces the warning:

match may not be exhaustive. It would fail on the following input: (x: Seq[?] forSome x not in Nil) def test(seq: Seq[_]): Unit = seq match {

Using case _ +: _ exhibits the same problem. Uncommenting the wildcard case allows compilation with no warnings.

This seems incorrect, in that it's evident when run that all the possible Seq cases are matched. The same test case using List with the same patterns also fails, but classic List cons patterns do not exhibit the problem.

timw commented 1 year ago

On reflection, I might be expecting too much of the compiler here, as it probably lacks enough information to know that these cases are exhaustive - the warning is "may not be exhaustive" after all, but the fact that there's a case that seems to obviously match the proposed failure pattern seems slightly jarring.

som-snytt commented 1 year ago

IIUC, https://github.com/scala/bug/issues/12240 is why case Seq(_@_*) => correctly does not warn, and this ticket is a duplicate of https://github.com/scala/bug/issues/12252

There is discussion via linked tickets.