-
Enhancement
-
Resolution: Fixed
-
P4
-
19
In Java 19, JEP 427 "Pattern Matching for switch (Third Preview)" expands the grammar of a switch label to allow patterns with _guards_:
SwitchLabel:
CaseOrDefaultLabel {: CaseOrDefaultLabel }
CaseOrDefaultLabel:
case CaseElement {, CaseElement }
default
CaseElement:
CaseConstant
Pattern { Guard }
null
default
Guard:
when Expression
Simultaneously, JEP 405 "Record Patterns (Preview)" expands the grammar for `Pattern`:
Pattern:
TypePattern
ParenthesizedPattern
RecordPattern
RecordPattern:
ReferenceType RecordStructurePattern [ Identifier ]
RecordStructurePattern:
( [ RecordComponentPatternList ] )
Unfortunately, taken together these two grammars create an ambiguity.
record R(){}
switch(e) {
case R() when when (true) -> ...
...
}
The label could be parsed as either:
case (R() when) when (true) ->
or
case (R()) when (when(true)) ->
(where `when` is a static boolean method).
There are three possible fixes to this ambiguity:
1. Require a named record pattern to use a new syntax, e.g. `R() as x`, so `case R() as when when (true)` is unambiguously `case (R() as when) when (true)`.
2. Exclude the identifier `when` from the universe of identifier names. (This would be a breaking change.)
3. Exclude the identifier `when` from the universe of unqualified method names. (This is similar to the treatment of `yield`, but is a breaking change.)
SwitchLabel:
CaseOrDefaultLabel {: CaseOrDefaultLabel }
CaseOrDefaultLabel:
case CaseElement {, CaseElement }
default
CaseElement:
CaseConstant
Pattern { Guard }
null
default
Guard:
when Expression
Simultaneously, JEP 405 "Record Patterns (Preview)" expands the grammar for `Pattern`:
Pattern:
TypePattern
ParenthesizedPattern
RecordPattern
RecordPattern:
ReferenceType RecordStructurePattern [ Identifier ]
RecordStructurePattern:
( [ RecordComponentPatternList ] )
Unfortunately, taken together these two grammars create an ambiguity.
record R(){}
switch(e) {
case R() when when (true) -> ...
...
}
The label could be parsed as either:
case (R() when) when (true) ->
or
case (R()) when (when(true)) ->
(where `when` is a static boolean method).
There are three possible fixes to this ambiguity:
1. Require a named record pattern to use a new syntax, e.g. `R() as x`, so `case R() as when when (true)` is unambiguously `case (R() as when) when (true)`.
2. Exclude the identifier `when` from the universe of identifier names. (This would be a breaking change.)
3. Exclude the identifier `when` from the universe of unqualified method names. (This is similar to the treatment of `yield`, but is a breaking change.)