-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #3332: Disallow bound variables in pattern alternatives #3429
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
Conversation
Disallow bound variables where the binder appears as a pattern alternative.
Maybe when we report this error we could add "did you mean |
Or maybe we need more backtracking in the parser :) |
One compromise could be: do backtracking under Scala2 mode but warn people when we backtrack that they should write |
@smarter It's actually worse than that. Here's some code that is legal now, but would mean something different if we changed the parsing scheme:
|
Actually, |
Here's a more complete transscript of what goes wrong: scala> case class A() scala> class B scala> (A(): Any) match { case _: B | A => "ok" case _ => "no" } That's the current behavior. If we change the parsing, we'd get "ok" instead. |
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.
It doesn't work in this case (_
seems to be treated as a variable):
class Test {
case class A()
def test(x: Any) = x match {
case _: String | _ @ A() => 1
}
}
15 | case _: String | _ @ A() => 1
| ^^^
| Illegal variable in pattern alternative
@@ -87,7 +90,7 @@ object Mode { | |||
/** Don't suppress exceptions thrown during show */ | |||
val PrintShowExceptions = newMode(18, "PrintShowExceptions") | |||
|
|||
val PatternOrType = Pattern | Type | |||
val PatternOrTypeBits = Pattern | Type | InPatternAlternative |
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.
Why did you rename this value? I think the old name is more consistent with the other mode's name
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.
It's because otherwise we'd risk that someone thinks it's Pattern | Type
only. And PatternOrTypeorInPatternAlternative
was too long.
I thought that `_` never appears as a bound variable in a bind but was wrong. We now rewrite `(_ @ P)` to `P`.
@allanrenucci The failure should be fixed now. |
This is a bit off-topic at this point, but I would argue that we're not doing anyone any favour by accepting this without at least a warning: it's extremely rare to want to pattern match on the companion object of a case class and is most likely to happen when trying to pattern match on the case class itself. I would rewrite |
Disallow bound variables where the binder appears as a pattern alternative.
Fixes #3332.
There's nothing we can do about the parsing. If we parsed
as
then we would run into an error for
But the latter is a common idiom.