RFR: 8366968: Exhaustive switch expression rejected by for not covering all possible values
Jan Lahoda
jlahoda at openjdk.org
Mon Sep 29 13:18:44 UTC 2025
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.
-------------
Depends on: https://git.openjdk.org/jdk/pull/27253
Commit messages:
- 8366968: Exhaustive switch expression rejected by for not covering all possible values
Changes: https://git.openjdk.org/jdk/pull/27547/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27547&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8366968
Stats: 43 lines in 2 files changed: 36 ins; 1 del; 6 mod
Patch: https://git.openjdk.org/jdk/pull/27547.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/27547/head:pull/27547
PR: https://git.openjdk.org/jdk/pull/27547
More information about the compiler-dev
mailing list