JDK-8294946 : Compiler implementation for Pattern Matching for switch (Fourth Preview)
  • Type: CSR
  • Component: tools
  • Sub-Component: javac
  • Priority: P4
  • Status: Provisional
  • Resolution: Unresolved
  • Fix Versions: 20
  • Submitted: 2022-10-07
  • Updated: 2022-10-28
Related Reports
CSR :  
Description
# Summary

Based on experiences with previous round of preview of pattern matching for switch, we propose a few improvements and simplifications of the feature.

# Problem

Three issues related to pattern matching in switch have been identified:

 * the grammar and validity conditions for case labels are too complex both to specify and understand. We propose to re-specify these conditions to be simpler and more understabable,
 * certain switch statements and expressions are not considered exhaustive, although they are obviously exhaustive. The specification is adjusted to make these switches exhaustive,
 * when the record pattern type (in switch statements and expressions, or another pattern matching construct) is a generic type, the user must currently provide explicit type arguments. But, due to various constraints, the set of valid type arguments is very small, and reasonable type arguments could be inferred automatically.

# Solution

## Updated case Structure

The current specification allows several complex constructs:

 * nullable type patterns, like `case null, String s`, or `case null: case String s:` and alike. These are too complex to specify and understand, and we propose to drop these.
 * the newly introduced `default` and `null` case labels are permitted in combination with various other labels, in a arbitrary order, which is unnecessary complex.
 * the `default` case does not need to be last in the switch, causing confusion.

In this update, we propose to:

 * case labels `null` and `default` will only be allowed as `case null` and `case null, default`, these two case labels are not permitted in any other order and do not combine with any other case label, including type patterns.
 * the dominance rules are updated to force `default` to be last case (label) for enhanced (new) switch statements and expressions.
 * fall-through rules for switch block statement rules are simplified, and disallow fall-through based on presence of binding variables observable from statements, rather than based on pattern types.

Please note that for pre-pattern matching switch statements and expressions, no changes are proposed, and these can still have `default` case at any position in the switch block.

## Not Exhaustive Switch Statements and Expressions

A class of switch statements and expressions are currently not considered exhaustive, despite being obviously exhaustive. For example:

```
sealed interface I<T> {}
record R<T>(T t) implements I<T> {}

I<String> i = ...;

switch (i) {
     case R<String>(String s) -> {}
}
```

This is considered non-exhaustive, because the expected type of the `R`'s component is `Object`, despite being obviously `String`. The proposed change is to change the exhaustiveness algorithm to infer and use the correct record component's type, which will make switch statements and expressions like this exhaustive.

## Record Pattern Type Inference

Consider code like:

```
List<String> l = ....;

switch (l) {
    case ArrayList<String> al -> {}
     ...
}
```

The current specification requires explicit type parameters for `ArrayList`,
although there are only very few possible meaningful type arguments, with
minimal differences. The proposal is to introduce type inference for type
arguments in record patterns, inferring meaningful types for the type arguments.



## Preview Status

The pattern matching for switch feature will continue to be a preview feature.

# Specification

The preliminary specification draft is available for convenience here: http://cr.openjdk.java.net/~gbierman/jep432%2b433/jep432%2b433-20221028/specs/patterns-switch-record-patterns-jls.html and is attached as jls-jep432+433-20221028.zip. Please note that, for technical reasons, the specification draft also includes changes for JEP-432 (https://openjdk.org/jeps/432), which are reviewed under CSR JDK-8294944.

There are no API changes proposed under this CSR.

Comments
[~darcy] I have added the updated spec that includes type inference for record patterns. We have decided to drop type inference for type patterns (using a `<>`) so I have edited the description accordingly.
28-10-2022

Moving to Provisional.
20-10-2022