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

Case classes with additional custom unapply produce pattern match warning #12250

Closed
jbwheatley opened this issue Nov 26, 2020 · 5 comments · Fixed by scala/scala#9462
Closed
Assignees
Milestone

Comments

@jbwheatley
Copy link

reproduction steps

using Scala 2.13.4, I have a case class with an additional custom unapply method.

final case class Foo(value: String)

object Foo {
  def unapply(str: String): Option[Foo] = Some(Foo(str))

  def extract(id: Foo): String =
    id match {
      case Foo(a) => a
    }
}

problem

Gives a warning:

match may not be exhaustive.
[warn] It would fail on the following input: Foo(_)
[warn]     id match {
[warn]     ^

Adding a further unapply method as suggested here #12232 did make the warning go away:

def unapply(arg: Foo): Some[String] = Some(arg.value)

However, the discussion on that issue seemed to point to not using case classes as the root of the problem. It seems like a bit of a gotcha that adding another unapply method breaks the out-of-the-box pattern matching for case classes.

@joroKr21
Copy link
Member

If I'm not mistaken the custom unapply is not additional but completely replaces the generated one.

@jbwheatley
Copy link
Author

jbwheatley commented Nov 26, 2020

The generated unapply still works: https://scastie.scala-lang.org/u7WW2ykKTKu9KUukQUaZWg

Edit: And I've been happily using this pattern on scala 2.13.3 without the warning, and without adding

def unapply(arg: Foo): Some[String] = Some(arg.value)

@joroKr21
Copy link
Member

Oh sorry I didn't notice the signature in your original example is swapped:

  def unapply(str: String): Option[Foo] = Some(Foo(str))

@dwijnand dwijnand self-assigned this Nov 26, 2020
@dwijnand dwijnand added this to the 2.13.5 milestone Nov 26, 2020
@dwijnand
Copy link
Member

Sadly it looks like making that extract-and-convert unapply irrefutable doesn't fix this:

def unapply(str: String): Some[Foo] = Some(Foo(str))

@jbwheatley
Copy link
Author

@dwijnand Yeah I had also tried that 😕

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants