import java.util.Optional; record PrimitiveAndSealed(int x, I y) {} record NormalAndSealed(Integer x, I y) {} sealed interface Super permits SuperChild, SuperRecord {} final class SuperChild implements Super {} record SuperRecord(I i) implements Super {} record Generic(T x) {} class A {} class B extends A {} sealed interface I permits C, D {} final class C implements I {} final class D implements I {} record Pair(T x, T y) {} record Top(Child c1, Child c2) {} record Child(I x, I y){} class Basic { String o; Super superInterface; SuperRecord superRecord; PrimitiveAndSealed primitiveAndSealed; NormalAndSealed normalAndSealed; Generic genericInterface; Generic genericC; void testGenerics(T p, Pair pair1, Pair pair2) { switch (p) { case SuperChild superChild -> {} case SuperRecord(C i) -> {} case SuperRecord(D i) -> {} } switch(p) { case SuperChild sc -> {} case SuperRecord sr -> {} } switch (pair1.x()) { case SuperChild sc -> {} case SuperRecord sr -> {} } switch (pair2.x()) { case SuperChild sc -> {} case SuperRecord sr -> {} } } void test(){ switch (superInterface) { //completed sealed with record case SuperChild superChild -> {} case SuperRecord(C i) -> {} case SuperRecord(D i) -> {} } switch (superInterface) { case SuperChild superChild -> {} case SuperRecord(C i) -> {} case SuperRecord(I i) -> {} } switch (superInterface) { case SuperChild superChild -> {} case SuperRecord(C i) -> {} case SuperRecord(I i) when i.hashCode() > 0 -> {} } switch (o) { //non-record is completed case String o -> {} } switch (superRecord) { case SuperRecord(C i) -> {} } switch (superRecord) { case SuperRecord(I i) -> {} } switch (primitiveAndSealed){ //error case PrimitiveAndSealed(int x, C y) -> {} } switch (primitiveAndSealed){ case PrimitiveAndSealed(int x, I y) -> {} } switch (primitiveAndSealed){ case PrimitiveAndSealed(int x, C y) -> {} case PrimitiveAndSealed(int x, D y) -> {} } switch (normalAndSealed){ //error case NormalAndSealed(Integer x, C y) -> {} } switch (normalAndSealed){ case NormalAndSealed(Integer x, I y) -> {} } switch (normalAndSealed){ case NormalAndSealed(Integer x, C y) -> {} case NormalAndSealed(Integer x, D y) -> {} } switch (genericInterface) { case Generic(I i) -> {} } switch (genericInterface) { case Generic(C i) -> {} } switch (genericInterface) { case Generic(C i) -> {} case Generic(D i) -> {} } switch (genericC) { case Generic(C i) -> {} } } void testNested(Top t){ switch (t){ case Top(Child(I x1, C y1), Child(C x2, I y2)) -> {} case Top(Child(I x1, D y1) , Child(I x2, C y2)) -> {} } switch (t){ case Top(Child(I x1, C y1) , Child c2) -> {} case Top(Child(I x1, D y1) , Child c2) -> {} } switch (t){ case Top(Child(I x1, C y1) , Child(I x2, I y2) ) -> {} case Top(Child(I x1, D y1) , Child(I x2, I y2) ) -> {} } switch (t){ case Top(Child c1, Child(C x2, I y2) ) -> {} case Top(Child c1, Child(I x2, C y2) ) -> {} } switch (t){ case Top(Child(I x1, C y1) , Child(I x2, I y2) ) -> {} case Top(Child(C x1, I y1) , Child(I x2, I y2) ) -> {} } switch (t){ case Top(Child(I x1, I y1) , Child(I x2, I y2) ) -> {} } } void test(Pair pairA, Pair pairI) { switch (pairA) { // Error! case Pair(A a,B b) -> { } case Pair(B b,A a) -> { } } switch (pairI) { // Error! case Pair(C fst, D snd) -> {} case Pair(D fst, C snd) -> {} case Pair(I fst, C snd) -> {} } switch (pairI) { case Pair(I i,C c) -> { } case Pair(I i,D d) -> { } } switch (pairI) { case Pair(C c,C i) -> { } case Pair(C c,D i) -> { } case Pair(D d,C c) -> { } case Pair(D d,D d2) -> { } } switch (pairI) { case Pair(C c,I i) -> { } case Pair(D d,C c) -> { } case Pair(D d,D d2) -> { } } switch(pairI.x()) { case C c when true -> {} case D d -> {} } } record R(int x) { } void emptyRecord(R r) { switch (r) { //error } } void emptyRecord2(R r) { switch (r) { //error case null -> System.out.println("1"); } } void emptyRecord3(R r) { switch (r) { //error case R r2 when r2.x() == 1 -> System.out.println("1"); } } void emptyInteger(int i) { switch (i) { } } void emptyObject0(Object o) { switch (o) { //error } } void emptyObject(Object o) { switch (o) { //error case null -> System.out.println(1); } } void emptyObject2(Object o) { switch (o) { case String s when s.length()==1 -> System.out.println(1); } } void emptyRecord4(R r) { switch (r) { case R r2 when r2.x() == 1 -> System.out.println(1); case R r2 -> System.out.println("1"); } } void emptyRecord5(R r) { switch (r) { //error case R r2 when r2.x() == 1 -> System.out.println(1); } } void emptyRecord6(R r) { switch (r) { default -> System.out.println("1"); } } //see com.intellij.codeInsight.daemon.impl.analysis.PatternHighlightingModel.reduceRecordPatterns void exhaustinvenessWithInterface(Pair pairI) { switch (pairI) { case Pair(C fst, D snd) -> {} case Pair(I fst, C snd) -> {} case Pair(D fst, I snd) -> {} } } //see com.intellij.codeInsight.daemon.impl.analysis.PatternHighlightingModel.reduceRecordPatterns void exhaustinvenessWithInterface2(Pair pairI) { switch (pairI) { case Pair(C fst, D snd) -> {} case Pair(I fst, C snd) -> {} case Pair(D fst, I snd) -> {} } } sealed interface A1 permits A11, A12 {} sealed interface A2 permits A21, A22 {} record A11() implements A1 {} record A12() implements A1 {} record A21() implements A2 { } record A22() implements A2 { } record R1(A2 a2) { } record R2(A1 a1, R1 r1) { } record R12(A1 a1, A2 a2) { } record R21(A2 a2, A1 a1) { } void exhaustivenessWithCrossSectionNestedRecords(R2 r2) { switch (r2) { case R2(A11 b1, R1(A2 b2)) -> System.out.println("1"); case R2(A12 b1, R1(A22 b2)) -> System.out.println("2"); case R2(A1 b1, R1(A21 b2)) -> System.out.println("3"); } } void exhaustivenessWithCrossSection1(R12 r12) { switch (r12) { case R12(A11 b1, A2 b2) -> System.out.println("1"); case R12(A12 b1, A22 b2) -> System.out.println("2"); case R12(A1 b1, A21 b2) -> System.out.println("3"); } } void exhaustivenessWithCrossSection2(R21 r21) { switch (r21) { case R21(A2 b2, A11 b1) -> System.out.println("1"); case R21(A22 b2, A12 b1) -> System.out.println("2"); case R21(A21 b2, A1 b1) -> System.out.println("3"); } } sealed interface Parent {} record AAA() implements Parent {} record BBB() implements Parent {} void test(Optional optional) { switch (optional.get()) { case AAA a -> {} case BBB b -> {} } } class CCCC{} public > void test(T c) { switch (c) { case Comparable t -> System.out.println(13); } } interface II1{} sealed interface II2{} non-sealed class Cl1 implements II2{} public void test(T c) { switch (c) { case Cl1 t: System.out.println(21); ; } } sealed interface J permits En, FC { } enum En implements J {A, B} final class FC implements J { } static int testExhaustive2(J ji) { return switch (ji) { case FC c -> 42; case En.A -> 0; case En.B -> 0; }; } record PairT(T t1, T t2) { } sealed interface T { } sealed interface T1 extends T { } sealed interface T2 extends T { } record T11(T t1, T t2) implements T1 { } record T12(T t1, T t2) implements T1 { } record T21(T t1, T t2) implements T2 { } record T22(T t1, T t2) implements T2 { } public void test1(PairT pairT) { switch (pairT) { case PairT(T11 t1, T1 t2) -> System.out.println(1); case PairT(T12 t1, T1 t2) -> System.out.println(1); case PairT(T1 t1, T2 t2) -> System.out.println(1); case PairT(T2 t1, T t2) -> System.out.println(1); } } public void test2(PairT pairT) { switch (pairT) { //error case PairT(T11 t1, T1 t2) -> System.out.println(1); case PairT(T12 t1, T1 t2) -> System.out.println(1); case PairT(T2 t1, T t2) -> System.out.println(1); } } public void test3(PairT pairT) { switch (pairT) { case PairT(T1 t1, T11 t2) -> System.out.println(1); case PairT(T1 t1, T12 t2) -> System.out.println(1); case PairT(T2 t1, T1 t2) -> System.out.println(1); case PairT(T t1, T2 t2) -> System.out.println(1); } } public void test4(PairT pairT) { switch (pairT) { case PairT(T1 t1, T11(T1 t12, T2 t22)) -> System.out.println(53714); case PairT(T1 t1, T11(T2 t12, T2 t22)) -> System.out.println(1); case PairT(T1 t1, T11(T t12, T1 t22)) -> System.out.println(1); case PairT(T1 t1, T12 t2) -> System.out.println(1); case PairT(T2 t1, T1 t2) -> System.out.println(1); case PairT(T t1, T2 t2) -> System.out.println(1); } } public void test5(PairT pairT) { switch (pairT) {//error case PairT(T1 t1, T11(T1 t12, T2 t22)) -> System.out.println(53714); case PairT(T1 t1, T11(T t12, T1 t22)) -> System.out.println(1); case PairT(T1 t1, T12 t2) -> System.out.println(1); case PairT(T2 t1, T1 t2) -> System.out.println(1); case PairT(T t1, T2 t2) -> System.out.println(1); } } public void test6(PairT pairT) { switch (pairT) { case PairT(T1 t1, T11(T1 t12, T2 t22)) -> System.out.println(53714); case PairT(T1 t1, T11(T2 t12, T2 t22)) -> System.out.println(1); case PairT(T1 t1, T11(T t12, T1 t22)) -> System.out.println(1); case PairT(T1 t1, T12(T1 t12, T t22)) -> System.out.println(1); case PairT(T1 t1, T12(T2 t12, T t22)) -> System.out.println(1); case PairT(T2 t1, T1 t2) -> System.out.println(1); case PairT(T t1, T2 t2) -> System.out.println(1); } } public void test7(PairT pairT) { switch (pairT) { case PairT(T11(T1 t12, T2 t22), T1 t1) -> System.out.println(53714); case PairT(T11(T2 t12, T2 t22), T1 t1) -> System.out.println(1); case PairT(T11(T t12, T1 t22), T1 t1) -> System.out.println(1); case PairT(T12(T1 t12, T t22), T1 t1) -> System.out.println(1); case PairT(T12(T2 t12, T t22), T1 t1) -> System.out.println(1); case PairT( T1 t2, T2 t1) -> System.out.println(1); case PairT( T2 t2, T t1) -> System.out.println(1); } } public void test8(PairT pairT) { switch (pairT) { case PairT(T11(T1 t12, T2 t22), T1 t1) -> System.out.println(53714); case PairT(T11(T2 t12, T2 t22), T1 t1) -> System.out.println(1); case PairT(T11(T t12, T1 t22), T1 t1) -> System.out.println(1); case PairT(T12(T1 t12, T t22), T1 t1) -> System.out.println(1); case PairT(T12(T2 t12, T t22), T1 t1) -> System.out.println(1); case PairT( T1 t2, T21 t1) -> System.out.println(1); case PairT( T1 t2, T22(T t11, T1 t12)) -> System.out.println(1); case PairT( T1 t2, T22(T t11, T2 t12)) -> System.out.println(1); case PairT( T2 t2, T t1) -> System.out.println(1); } } public void test9(PairT pairT) { switch (pairT) { case PairT(T11(T1 t12, T2 t22), T1 t1) when ((Object)pairT).hashCode()==1 -> System.out.println(53714); case PairT(T11(T2 t12, T2 t22), T1 t1) -> System.out.println(1); case PairT(T11(T t12, T1 t22), T1 t1) -> System.out.println(1); case PairT(T12(T1 t12, T t22), T1 t1) -> System.out.println(1); case PairT(T12(T2 t12, T t22), T1 t1) -> System.out.println(1); case PairT( T1 t2, T21 t1) -> System.out.println(1); case PairT( T1 t2, T22(T t11, T1 t12)) -> System.out.println(1); case PairT( T1 t2, T22(T t11, T2 t12)) -> System.out.println(1); case PairT( T2 t2, T t1) -> System.out.println(1); } } sealed interface TInt {} final class TI1 implements TInt {} final class TI2 implements TInt {} record RR(String s, TInt i) {} void test(RR r) { switch (r) { case RR(CharSequence c1, TI1 c2) -> System.out.println("1"); case RR(Object c1, TI2 c2) -> System.out.println("2"); } } class OnlyDirectChildren{ sealed interface T permits T1, T2, T3 {} sealed interface T1 extends T permits T12 {} sealed class T2 implements T {} sealed interface T3 extends T {} final class T12 extends T2 implements T1 {} final class T13 implements T3 {} void test(T i) { switch (i) { case T2 i2 -> System.out.println("2"); case T13 i3 -> System.out.println("3"); } } void test2(T i) { switch (i) { case T2 i2 -> System.out.println("2"); case T1 i1 -> System.out.println("1"); case T13 i3 -> System.out.println("3"); } } } class Intersection{ sealed interface T1 { } sealed interface T2 { } final class T11 implements T1 { } final class T12 implements T2 { } final class T112 implements T1, T2 { } record Pair(L a){} void test(A z) { switch (z) { case T112 c -> System.out.println("1"); } } void test(Pair z) { switch (z) { case Pair(T112 c) -> System.out.println("23875"); } } } class EmptyStatement(){ sealed class A {} final class AA extends A {} sealed class AB extends A {} non-sealed class AC extends A {} final class ABA extends AB {} non-sealed class ABC extends AB {} void test(A a) { switch (a) { } } } }