scala / bug

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

Seemingly false "match may not be exhaustive" warning for final classes with hand-written extractors with `-Xlint` #12913

Closed MF42-DZH closed 7 months ago

MF42-DZH commented 7 months ago

Reproduction steps

Scala version: 2.13.12 Java version: 17.0.1

package example

object UnapplyNonExhaustive {
  final class Foo(val x: Int)
  object Foo {
    def unapply(f: Foo): Option[Int] =
      Some(f.x)
  }

  val nonExhaustiveWarning: Unit = new Foo(1) match {
    case Foo(x) => println(x)
  }

  val alsoHere: Unit = {
    val Foo(x) = new Foo(1)
    println(x)
  }
}

Compile with -Xlint.

Example SBT project that reproduces: nonexhaustiveexample-frozen.zip

Problem

With -Xlint, both pattern matches emit a match may not be exhaustive warning with no counter-examples, despite Foo being a final class with no other candidates for the match. Expected behaviour is either no warning, or some counter-examples (even if that is null).

Example output from SBT:

[warn] /home/azl/nonexhaustiveexample/src/main/scala/example/Hello.scala:10:36: match may not be exhaustive.
[warn]   val nonExhaustiveWarning: Unit = new Foo(1) match {
[warn]                                    ^
[warn] /home/azl/nonexhaustiveexample/src/main/scala/example/Hello.scala:15:18: match may not be exhaustive.
[warn]     val Foo(x) = new Foo(1)
[warn]                  ^
[warn] two warnings found
SethTisue commented 7 months ago

The extractor is considered refutable because its return type is Option. If you make the return type Some, it will be irrefutable.