Skip to content

Conversation

lahodaj
Copy link
Contributor

@lahodaj lahodaj commented Sep 29, 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.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Integration blocker

 ⚠️ Dependency #27253 must be integrated first

Issue

  • JDK-8366968: Exhaustive switch expression rejected by for not covering all possible values (Bug - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/27547/head:pull/27547
$ git checkout pull/27547

Update a local copy of the PR:
$ git checkout pull/27547
$ git pull https://git.openjdk.org/jdk.git pull/27547/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 27547

View PR using the GUI difftool:
$ git pr show -t 27547

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/27547.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Sep 29, 2025

👋 Welcome back jlahoda! A progress list of the required criteria for merging this PR into pr/27253 will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Sep 29, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk bot changed the title 8366968: Exhaustive switch expression rejected by for not covering al… 8366968: Exhaustive switch expression rejected by for not covering all possible values Sep 29, 2025
@openjdk
Copy link

openjdk bot commented Sep 29, 2025

@lahodaj The following label will be automatically applied to this pull request:

  • compiler

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the rfr Pull request is ready for review label Sep 29, 2025
@mlbridge
Copy link

mlbridge bot commented Sep 29, 2025

Webrevs

@lahodaj lahodaj marked this pull request as draft October 1, 2025 05:47
@openjdk openjdk bot removed the rfr Pull request is ready for review label Oct 1, 2025
@lahodaj lahodaj marked this pull request as ready for review October 2, 2025 09:05
@openjdk openjdk bot added the rfr Pull request is ready for review label Oct 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler [email protected] rfr Pull request is ready for review
Development

Successfully merging this pull request may close these issues.

1 participant