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

Scala pattern match is not exhaustive on nested case classes #9630

Closed
scabug opened this issue Jan 25, 2016 · 7 comments
Closed

Scala pattern match is not exhaustive on nested case classes #9630

scabug opened this issue Jan 25, 2016 · 7 comments
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Jan 25, 2016

Hi,

I've got a case class hierarchy to encode some request and processing errors:

sealed trait OpError
sealed trait RequestErrorType
sealed trait ProcessingErrorType

final case class InvalidEndpoint(reason: String) extends RequestErrorType
final case class InvalidParameters(reason: String) extends RequestErrorType

final case class InvalidFormat(response: String) extends ProcessingErrorType
final case class EntityNotFound(id: Long) extends ProcessingErrorType

final case class RequestError(errorType: RequestErrorType) extends OpError
final case class ProcessingError(errorType: ProcessingErrorType) extends OpError

If I write a simple match across all patterns:

def printMatches(error: OpError): Unit = error match {
  case RequestError(InvalidEndpoint(reason)) => //print something
  case RequestError(InvalidParameters(reason)) => //print something
  case ProcessingError(InvalidFormat(format)) => //print something
  case ProcessingError(EntityNotFound(entityId)) => //print something
}

the compiler gives me a warning about missing match:

match may not be exhaustive.
 It would fail on the following input: ProcessingError(_)
 def printMatches(error: OpError): Unit = error match {

ProcessingError takes in a ProcessingErrorType with only two extensions: InvalidFormat and EntityNotFound, both which are accounted for in the pattern match.

@scabug
Copy link
Author

scabug commented Jan 25, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9630?orig=1
Reporter: sanjiv sahayam (sanjsmailbox-at-gmail.com)

@scabug
Copy link
Author

scabug commented Jan 25, 2016

sanjiv sahayam (sanjsmailbox-at-gmail.com) said:
Could be linked to scala/scala#2737 as per @Retronyms suggestion.

@scabug
Copy link
Author

scabug commented Jan 25, 2016

@retronym said (edited on Jan 25, 2016 9:26:50 AM UTC):
A workaround appears to be to chose different names for the field of RequestError and ProcessingError.

Here's a slightly minimized version:

sealed trait Base
final case class Base_1(sameName: Some[Any]) extends Base
final case class Base_2(sameName: Nested) extends Base

sealed trait Nested
final case class Nested_1(x: Any) extends Nested
final case class Nested_2(y: Any) extends Nested

class Test {
  def test(b: Base): Unit = b match {
    case Base_1(Some(_)) =>
    case Base_2(Nested_1(_)) =>
    case Base_2(Nested_2(_)) =>
  }
}

@scabug
Copy link
Author

scabug commented Jan 25, 2016

@retronym said:
Here's a potential fix: https://github.com/scala/scala/compare/2.12.x...retronym:ticket/9630?expand=1

I'll discuss this bug with @adriaanm to see if that's the right way forward.

@scabug
Copy link
Author

scabug commented Jan 25, 2016

sanjiv sahayam (sanjsmailbox-at-gmail.com) said:
Thanks for looking into this Jason. I can verify that the workaround works! :)

It does seem weird that the name of a parameter would lead to this bug.

@scabug
Copy link
Author

scabug commented Jan 25, 2016

@retronym said:
It seems that that strangeness is the root cause for a few different bugs (including some mentioned by [~japgolly] on your mailing list thread.

See the additional test cases in https://github.com/scala/scala/compare/2.12.x...retronym:ticket/9630?expand=1 for more details.

Thanks for your report, which triggered me to look at these again with fresh eyes.

@scabug
Copy link
Author

scabug commented Jan 27, 2016

@retronym said:
scala/scala#4919

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

No branches or pull requests

2 participants