Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exhaustivity warning should tell you when outer pointer is the cause #10100

Open
scabug opened this issue Dec 8, 2016 · 3 comments
Open

Exhaustivity warning should tell you when outer pointer is the cause #10100

scabug opened this issue Dec 8, 2016 · 3 comments

Comments

@scabug
Copy link

scabug commented Dec 8, 2016

Example:

sealed trait Foo {
    val index: Int
}

case class BasicFoo(index: Int) extends Foo

class NonExhaustive {
    case class FancyFoo(index: Int) extends Foo

    def convert(foos: Vector[Foo]): Vector[Int] = {
        foos.foldLeft(Vector.empty[Int]) {
            case (acc, basic: BasicFoo) => acc :+ basic.index
            case (acc, fancy: FancyFoo) => acc :+ fancy.index
        }
    }
}

Output:

NonExhaustive.scala:15: match may not be exhaustive.
It would fail on the following input: (_, FancyFoo(_))
foos.foldLeft(Vector.empty[Int]) {
                                 ^

This doesn't make sense, because the code explicitly matches that pattern.

If I move the definition of FancyFoo out of NonExhaustive, the warning goes away.

@scabug
Copy link
Author

scabug commented Dec 8, 2016

Imported From: https://issues.scala-lang.org/browse/SI-10100?orig=1
Reporter: Benjamin Geer (benjamingeer)
Affected Versions: 2.12.1

@liufengyun
Copy link

The compiler is actually correct here (Dotty also reports a warning). It's possible to for the pattern match to fail at runtime:

sealed trait Foo {
  val index: Int
}

case class BasicFoo(index: Int) extends Foo

class NonExhaustive {
  case class FancyFoo(index: Int) extends Foo

  def convert(foos: Vector[Foo]): Vector[Int] = {
    foos.foldLeft(Vector.empty[Int]) {
      case (acc, basic: BasicFoo) => acc :+ basic.index
      case (acc, fancy: FancyFoo) => acc :+ fancy.index
    }
  }
}

@main
def Test = {
  val a = new NonExhaustive
  val b = new NonExhaustive

  val fa: Foo = a.FancyFoo(3)
  val fb: Foo = b.FancyFoo(4)

  a.convert(Vector(fa, fb))
}

@dwijnand
Copy link
Member

Agreed. But there's still a UX bug: neither the message nor the counter-examples explain that it's to do with the outer pointer.

@SethTisue SethTisue added this to the Backlog milestone Aug 26, 2023
@SethTisue SethTisue changed the title Incorrect warning about non-exhaustive match with inner class Exhaustivity warning should tell you when outer pointer is the cause Aug 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants