Integrated: 8366968: Exhaustive switch expression rejected by for not covering all possible values

Jan Lahoda jlahoda at openjdk.org
Thu Oct 30 07:11:12 UTC 2025


On Mon, 29 Sep 2025 13:10:59 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:

> Consider case like (from the bug):
> 
> class Demo {
> 
>     sealed interface Base permits Special, Value {}
> 
>     non-sealed interface Value extends Base {}
> 
>     sealed interface Special extends Base permits SpecialValue {}
> 
>     non-sealed interface SpecialValue extends Value, Special {}
> 
>     static int demo(final Base base) {
>         return switch (base) {
>             case final Value value -> 0;
>             // Uncommenting the following line will make javac accept this program
>             //case final Special value -> throw new AssertionError();
>         };
> 
>     }
> 
> }
> 
> 
> This fails to compile:
> 
> /tmp/Demo.java:12: error: the switch expression does not cover all possible input values
>         return switch (base) {
>                ^
> 1 error
> 
> 
> Note there is no instance of `Special` that would not be an instance of `Value` as well. I.e. covering `Value` will catch all input.
> 
> Also, note that if `case Value` is replaced with `case SpecialValue`, javac also compile the code:
> 
>             case final Value value -> 0;
> =>
>             case final SpecialValue value -> 0;
> 
> $ ~/tools/jdk/jdk-25/bin/javac /tmp/Demo.java
> $
> 
> 
> Which shows the problem: replacing a type with a super type should not cause the switch to stop to be exhaustive (i.e. the switch is exhaustive for `SpecialValue`, but replacing it with its super type `Value`, the switch is no longer exhaustive for javac).
> 
> javac contains a piece of code that searches through subtypes to handle diamond class hierarchies like the one above. But, when it searches for subtypes, it does a search through permitted subtypes of the type. And since `Value` is not sealed, this search will not find `SpecialValue`, and javac won't see the switch to be exhaustive.
> 
> The proposal herein is to broaden the search, and consider all transitive permitted subtypes of the selector type, and filter subtypes of the current type from this set (if the current type is abstract, if it is not abstract, we can't do the subtype search at all). This should, I think, include all relevant subtypes.

This pull request has now been integrated.

Changeset: 87a47721
Author:    Jan Lahoda <jlahoda at openjdk.org>
URL:       https://git.openjdk.org/jdk/commit/87a47721981bb84b1e22b5b2d8d24bc60c8b7223
Stats:     164 lines in 2 files changed: 145 ins; 11 del; 8 mod

8366968: Exhaustive switch expression rejected by for not covering all possible values

Reviewed-by: abimpoudis

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

PR: https://git.openjdk.org/jdk/pull/27547


More information about the compiler-dev mailing list