RFR: 8273328: Compiler implementation for Pattern Matching for switch (Second Preview)

Jan Lahoda jlahoda at openjdk.java.net
Thu Nov 4 13:19:10 UTC 2021


On Thu, 4 Nov 2021 12:59:27 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> The specification for pattern matching for switch (preview)[1] has been updated with two changes:
>> -any type of pattern (including guarded patterns) dominates constant cases. Dominance across pattern/non-constant cases is unchanged. (See the change in `Attr.java`.)
>> -for sealed hierarchies, it may happen some of the subtypes are impossible (not castable) to the selector type. Like, for example:
>> 
>> sealed interface I<T> {}
>> final class A implements I<String> {}
>> final class B<T> implements I<T> {}
>> ...
>> I<Integer> i = ...;
>> switch (i) {
>>      case A a -> {} //case not allowed as I<Integer> is not castable to A
>>      case B b -> {}
>> }
>> 
>> 
>> But, the exhaustiveness checks in JDK 17 required all the permitted subclasses, including `A`, are covered by the switch, which forced a `default` clause in place of `case A a` for cases like this. The updated specification excludes such impossible permitted subclasses from exhaustiveness checks, so the default is no longer needed and this:
>> 
>> 
>> I<Integer> i = ...;
>> switch (i) {
>>      case B b -> {}
>> }
>> 
>> 
>> compiles OK.
>> (See the change in `Flow.java`.)
>> 
>> [1] http://cr.openjdk.java.net/~gbierman/jep420/jep420-20211020/specs/patterns-switch-jls.html
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 788:
> 
>> 786: 
>> 787:         private boolean isTransitivelyCovered(Type seltype, Symbol sealed, Set<Symbol> covered) {
>> 788:             DeferredCompletionFailureHandler.Handler prevHandler =
> 
> Why do we need to guard against completion failures here in Flow?

Consider a case like this:

sealed interface I permits A, B {}
//A and B defined
...
I i = null;
switch (i) {
     case A -> {}
}


This will produce an error, because the switch is not exhaustive. Now, consider, in addition, that `B` is missing. It feels a bit harsh to produce an error about the missing `B` permitted subclass (possibly producing that error instead of the exhaustiveness error), as it seems plausible permitted subclasses may be missing during compilation.

-------------

PR: https://git.openjdk.java.net/jdk/pull/6209


More information about the compiler-dev mailing list