-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Change pattern matcher #2822
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
Change pattern matcher #2822
Conversation
As the saying goes: "let erasure handle it... " The reason for the change is that things were a mess before - isInstanceOfEvaluator did not handle &/| types. It would be hard to change that since it was looking at erased types. - isInstanceEvaluator, but not TypeTestCasts added null-checks - therefore, necessary null-checks were not emitted on some tests of the form `x.isInstanceOf[A & B]`. - the pattern matcher patched this up by inserting some null checks on its own, whereas it should just have let the translation of isInstanceOf do the job.
To be documented once we figured out whether it works.
The optimizer seems to do some optimizations regarding simplifications of pattern matchings. This masks errors to be reported later at erasure. The optimizer should perform these actions only after erasure.
- drop a test which prevented a check in isInstanceOfEvaluator but which can be dropped with the more precise types in TypeTestCasts - move a test which was only partially effective in RefChecks to TypeTestCasts (problem is again testing against &/| types).
IsInstanceOfEvaluator as prone to mispredict whether the test was generated by a pattern match or not. We fix this by having a special type test symbol that represents tests generated by a pattern match.
We had: scala> null.isInstanceOf[String] -- Warning: <console>:5:17 ----------------------------------------------------- 5 |null.isInstanceOf[String] |^^^^^^^^^^^^^^^^^^^^^^^^^ |this will always yield true if the scrutinee is non-null, since `Null` is a subclass of `String` (will be optimized away) val res0: Boolean = true scala> val x: AnyRef = null val x: AnyRef = null scala> x.isInstanceOf[String] val res1: Boolean = false Fixed by using `isNullable`.
No need to use inheritance here.
Surprisingly, this caused the IDE to crash with a MatchError. (previous pattern matcher, not new one). I could not work out why. But in any case it was the wrong pattern before.
This now special cases `x.isInstance[y.type]` to `x eq y` and similarly for constant types.
Warn if a match is @switch annotated but we could not transform code to a switch.
The new pattern matcher generates switches only for 3 or more cases. Update bytecode tests accordingly.
- better structure - better names - more extensive documentation
For now we keep the previous one around as PatternMatcherOld.scala
It turns out that when we restrict DropGoodCasts to isInstanceOf tests (as opposed to pattern-matcher generated type tests), we do not miss any error messages. Some warnings are still be omitted under optimize, not sure whether we want to fix that.
There was a problem hiding this 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! ❤️
Commit Messages
We want to keep history, but for that to actually be useful we have
some rules on how to format our commit messages (relevant xkcd).
Please stick to these guidelines for commit messages:
- Separate subject from body with a blank line
- When fixing an issue, start your commit message with
Fix #<ISSUE-NBR>:
- Limit the subject line to 72 characters
- Capitalize the subject line
- Do not end the subject line with a period
- Use the imperative mood in the subject line ("Added" instead of "Add")
- Wrap the body at 80 characters
- Use the body to explain what and why vs. how
adapted from https://chris.beams.io/posts/git-commit
Have an awesome day! ☀️
It seems there are more issues with local optimizations. I did not track down details but in one case positions were wrong after a rewrite. That was tryPatternMatchError.scala. We should track these problems down in a different PR.
Superseded by #2829. |
A rewrite of the pattern matcher. It
Based on #2820. The hardest part was actually to get #2820 right. Once that was done
it was possible to make steady progress on the pattern matcher itself.