Skip to content

Fix pattern matching alternative #5653

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

Closed
wants to merge 1 commit into from

Conversation

andrevidela
Copy link

@andrevidela andrevidela commented Dec 21, 2018

Fix #5402

The same problem was fixed in scalac in 2013 in this pull request scala/scala#2291

I've reused the same test cases. Though there is one other issue

a match {
  case 0 | 1 => 1
  case 1 => 0
}

Will also crash the compiler with the same error described in #5402 . Compiling this code in scalac
results in a "code unreachable" warning. This suggest to me that this bug should be fixed in the code path analysis phase and not the switch case generation.

Should this problem be fixed in another pull request?

Copy link
Member

@dottybot dottybot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, and thank you for opening this PR! 🎉

All contributors have signed the CLA, thank you! ❤️

Have an awesome day! ☀️

@andrevidela andrevidela force-pushed the fix-redundant-pattern branch from 72bf454 to a007673 Compare December 21, 2018 17:24
@andrevidela
Copy link
Author

andrevidela commented Dec 21, 2018

Actually, the unrechable code might be fixable in Space.scala and replace the warning by a unrechable case. @liufengyun @smarter what do you think, should I give it a go?

@liufengyun
Copy link
Contributor

Thanks @andrevidela , it's OK to just fix it in this PR.

@andrevidela andrevidela force-pushed the fix-redundant-pattern branch from a007673 to a744ee5 Compare December 22, 2018 14:06
@andrevidela andrevidela force-pushed the fix-redundant-pattern branch from a744ee5 to ccb813a Compare December 22, 2018 20:28
@andrevidela
Copy link
Author

@smarter I think this PR is ready, could you take a look?

@andrevidela
Copy link
Author

I just signed the CLA now

}

/** Flatten a list of patterns into a single tree */
private def simplifyCases(alts: List[Tree]): Tree = alts match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused?

case alt :: Nil => alt
case Nil => Underscore(defn.IntType) // default case
case _ => Alternative(alts)
private def emitSwitchCases(cases: List[(List[Tree], Plan)]): List[CaseDef] = cases.foldLeft((List[CaseDef](), List[Tree]())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally our code style is to prefer tail-recursive formulation over folds and to replace Option with sentinels. This generally increases clarity and avoids unnecessary allocations. Allocations are your enemy - they make the compiler slow, more than anything else. And since they are spread out, there are no hot spots to address, you really have to take care to avoid them everywhere as much as is reasonable.

So would prefer the old formulation of emitCases over the new one.

/** Remove cases that already appear in the same pattern or in previous patterns */
private def removeRedundantCases(previousCases: List[Tree], cases: List[Tree]): List[Tree] = cases.foldLeft(List[Tree]()) {
case (cases, alt) =>
if (cases.exists(_ === alt) || previousCases.exists(_ === alt)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quadratic in the number of cases. Maybe create a set of case values instead?

Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I would recommend to investigate a patch similar to the one for scalac.

@odersky
Copy link
Contributor

odersky commented Dec 30, 2018

I had a quick look myself and came up with #5663, which is more conservative. I took the test case from this PR. So I think we can close this one now. Anyway, thank you for looking into it!

@odersky odersky closed this Dec 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Switch with alternatives crashes
4 participants