Pattern matching for switch: Spec and Javac inconsistency

Ilyas Selimov ilyas.selimov at jetbrains.com
Tue Jun 22 11:38:21 UTC 2021


Hello!

I found several differences between some rules in the spec draft (
http://cr.openjdk.java.net/~gbierman/jep406/jep406-20210527/specs/patterns-switch-jls.html#jls-14.11.1
)
and its javac implementation (OpenJDK 17 build 17-ea+27-2476).
Maybe ones are intentional or I missed something during the past
discussions.

1)
Spec:
If a switch label has a constant case label element then if the switch
label also has other case element labels they must be either a constant
case label element, the default case label element, or the null case label
element.

The next code is compiled fine despite the existence of both constant and
pattern case label elements:
void testInt(Integer i) {
  switch (i) {
    case Integer o && o != null, 1:
      System.out.println("s1");
    default:
      System.out.println("def");
  }
}

while the similar code isn't compiled:

enum Day { MONDAY, TUESDAY, WEDNESDAY }
void testEnum(Day d) {
  switch (d) {
    case Day day && day != null, TUESDAY: // illegal fall-through to a
pattern
      System.out.println("day");
    default:
      System.out.println("def");
  }
}

2)
Spec:
If a switch label has a null case label element then if the switch label
also has any pattern case element labels, they must be type patterns
(14.30.1).

Does "must be be type patterns" mean here that I can't declare guarded
patterns together with
'null' label element like in the code below:
void testInt(Integer i) {
  switch (i) {
    case null, Integer o && o != null:
      System.out.println("s1");
    default:
      System.out.println("def");
  }
}

3)
Spec:
A switch label that has a pattern case label element p that is total for
the type of the selector expression of the enclosing switch statement or
switch expression dominates a switch label that has a 'null' label element.

Here are two similar code samples:
void testInt1(Integer i) {
  switch (i) {
    case Object o, null:
      System.out.println("s1");
  }
}

void testInt2(Integer i) {
  switch (i) {
    case Object o:
      System.out.println("s1");
    case null: // this case label is dominated by a preceding case label
      System.out.println("null");
  }
}

The first one compiles fine, while the second one is not.
The spec says only about dominance between label elements within separate
switch labels. Anyway, what is the main reason that allows the first sample
to be compiled?
'Object o' is a total for the type of the selector expression and it
dominates 'null',
so the 'null' label element looks redundant.

Thanks,
Ilyas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20210622/01ed2284/attachment-0001.htm>


More information about the compiler-dev mailing list