RFR: 8327368: javac crash when computing exhaustiveness checks.

Jan Lahoda jlahoda at openjdk.org
Mon Jun 3 12:51:09 UTC 2024


Consider code like:

package test;

public class Test {

    sealed interface A permits T, U {}

    sealed interface B permits V, W {}

    static final class T implements A {}

    static final class U implements A {}

    static final class V implements B {}

    static final class W implements B {}

    final static record R(A a, B b) {}

    static int r(R r) {
        return switch (r) {
            case R(A a, V b) -> 1;
            case R(T a, B b) -> 2;
            case R(U a, W b) -> 3;
        };
    }
}


To properly evaluate exhaustiveness, we need to consider `R(T a, B b)` to act as `R(T a, W b)`, so that we can reduce `R(T a, W b)` and `R(U a, W b)` to `R(A a, W b)`. Which is then reduced together with `R(A a, V b)` to `R(A a, B b)` and consequently to just `R`.

This was done under JDK-8325215, by expanding `B` into all possible subtypes, from which we can pick patterns for reduction. Eventually, that patch may need a more complete revamp, but the idea herein is just to prevent a `ClassCastException` when the type of the binding pattern is not a class-based type - typically, when it is a type variable. As type variables don't have subtypes, we cannot expand then to all possible subtypes anyway, and can simply skip them.

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

Commit messages:
 - 8327368: javac crash when computing exhaustiveness checks.

Changes: https://git.openjdk.org/jdk/pull/19523/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=19523&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8327368
  Stats: 37 lines in 2 files changed: 33 ins; 0 del; 4 mod
  Patch: https://git.openjdk.org/jdk/pull/19523.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/19523/head:pull/19523

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


More information about the compiler-dev mailing list