RFR: 8364991: Incorrect not-exhaustive error [v6]

Vicente Romero vromero at openjdk.org
Mon Oct 20 16:50:06 UTC 2025


On Mon, 20 Oct 2025 05:49:59 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:

>> Consider this code:
>> 
>> $ cat Test.java
>> package test;
>> public class Test {
>>     private int test1(Root r) {
>>         return switch (r) {
>>             case Root(R2(R1 _), R2(R1 _)) -> 0;
>>             case Root(R2(R1 _), R2(R2 _)) -> 0;
>>             case Root(R2(R2 _), R2(R1 _)) -> 0;
>>             case Root(R2(R2 _), R2 _) -> 0;
>>         };
>>     }
>>     sealed interface Base {}
>>     record R1() implements Base {}
>>     record R2(Base b1) implements Base {}
>>     record Root(R2 b2, R2 b3) {}
>> }
>> 
>> 
>> javac (JDK 25) will produce a compile-time error for this code:
>> 
>> $ javac test/Test.java
>> .../test/Test.java:4: error: the switch expression does not cover all possible input values
>>         return switch (r) {
>>                ^
>> 1 error
>> 
>> 
>> This error is not correct according to the JLS. JLS defines a set of possible reductions of pattern sets, and if there exists a series of reductions from the pattern set into a pattern set that covers the selector type, the switch is exhaustive.
>> 
>> One such reduction is that if there's a sub-set of (record) patterns that only differ in one component ("the mismatching component"), we can replace them with a (set of) patterns where this component is reduced, and the other components are unmodified.
>> 
>> Such path exists here (every line shows a set of patterns that is being transformed):
>> 
>> Root(R2(R1 _), R2(R1 _)), Root(R2(R1 _), R2(R2 _)), Root(R2(R2 _), R2(R1 _)), Root(R2(R2 _), R2 _)
>> => choosing the second component as the mismatching component, then we can reduce Root(R2(R1 _), R2(R1 _)), Root(R2(R1 _), R2(R2 _)) => Root(R2(R1 _), R2 _); as we can reduce R2(R1 _), R2(R2 _) to R2 _
>> Root(R2(R1 _), R2 _), Root(R2(R2 _), R2(R1 _)), Root(R2(R2 _), R2 _)
>> => choosing the first component as the mismatching component, we can reduce Root(R2(R1 _), R2 _), Root(R2(R2 _), R2 _) => Root(R2 _, R2 _)
>> Root(R2 _, R2 _)
>> =>
>> Root _
>> =>
>> exhaustive
>> 
>> 
>> The problem here is that in the first step, javac chooses this path:
>> 
>> Root(R2(R1 _), R2(R1 _)), Root(R2(R1 _), R2(R2 _)), Root(R2(R2 _), R2(R1 _)), Root(R2(R2 _), R2 _)
>> => reduce Root(R2(R1 _), R2(R1 _)),  Root(R2(R2 _), R2(R1 _)) => Root(R2 _, R2(R1 _))
>> Root(R2 _, R2(R1 _)), Root(R2(R1 _), R2(R2 _)), Root(R2(R2 _), R2 _)
>> => dead end, as there are no two patterns that would have the same nested pattern in the same component
>> 
>> 
>> If javac would do full backtracking, it could go back, and choose the other path, and find out the switch ...
>
> Jan Lahoda has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 557 additional commits since the last revision:
> 
>  - Merge branch 'JDK-8367499-2' into JDK-8364991
>  - 8367499: Refactor exhaustiveness computation from Flow into a separate class
>  - 8369685: RISC-V: refactor code related to RVFeatureValue::enabled
>    
>    Reviewed-by: fyang, rehn
>  - 8369814: G1: Relax card mark and store ordering
>    
>    Reviewed-by: tschatzl, fandreuzzi
>  - 8342659: Test vmTestbase/nsk/jdi/ObjectReference/referringObjects/referringObjects002/referringObjects002.java failed: Class nsk.share.jdi.TestClass1 was not unloaded
>    
>    Co-authored-by: Chris Plummer <cjplummer at openjdk.org>
>    Reviewed-by: sspitsyn, cjplummer
>  - 8369979: Flag UsePopCountInstruction was accidentally disabled on PPC64
>    
>    Reviewed-by: aph, mdoerr
>  - 8369924: Remove test/jdk/javax/management/remote/mandatory/loading/MissingClassTest.java from problemlist
>    
>    Reviewed-by: sspitsyn
>  - 8341381: Random lines appear in graphic causing by the fix of JDK-8297230
>    
>    Reviewed-by: prr
>  - 8068310: [TEST_BUG] Test javax/swing/JColorChooser/Test4234761.java fails with GTKL&F
>    
>    Reviewed-by: serb
>  - 8342401: [TESTBUG] javax/swing/JSpinner/8223788/JSpinnerButtonFocusTest.java test fails in ubuntu 22.04 on SBR Hosts
>    
>    Reviewed-by: honkar, serb
>  - ... and 547 more: https://git.openjdk.org/jdk/compare/25d1b956...0290ecb0

lgtm, nice job!

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

Marked as reviewed by vromero (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/27247#pullrequestreview-3357213136


More information about the compiler-dev mailing list