mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 05:15:22 +00:00
8364991: Incorrect not-exhaustive error
This commit is contained in:
parent
078d0d4968
commit
2cfbc715c0
@ -822,6 +822,7 @@ public class Flow {
|
||||
}
|
||||
}
|
||||
Set<PatternDescription> patterns = patternSet;
|
||||
Set<Set<PatternDescription>> seenFallback = new HashSet<>();
|
||||
boolean useHashes = true;
|
||||
try {
|
||||
boolean repeat = true;
|
||||
@ -843,7 +844,7 @@ public class Flow {
|
||||
//but hashing in reduceNestedPatterns will not allow that
|
||||
//disable the use of hashing, and use subtyping in
|
||||
//reduceNestedPatterns to handle situations like this:
|
||||
repeat = useHashes;
|
||||
repeat = useHashes && seenFallback.add(updatedPatterns);
|
||||
useHashes = false;
|
||||
} else {
|
||||
//if a reduction happened, make sure hashing in reduceNestedPatterns
|
||||
@ -1083,15 +1084,24 @@ public class Flow {
|
||||
for (int i = 0; i < rpOne.nested.length; i++) {
|
||||
if (i != mismatchingCandidate) {
|
||||
if (!rpOne.nested[i].equals(rpOther.nested[i])) {
|
||||
if (useHashes ||
|
||||
//when not using hashes,
|
||||
//check if rpOne.nested[i] is
|
||||
//a subtype of rpOther.nested[i]:
|
||||
!(rpOne.nested[i] instanceof BindingPattern bpOne) ||
|
||||
!(rpOther.nested[i] instanceof BindingPattern bpOther) ||
|
||||
!types.isSubtype(types.erasure(bpOne.type), types.erasure(bpOther.type))) {
|
||||
if (useHashes) {
|
||||
continue NEXT_PATTERN;
|
||||
}
|
||||
//when not using hashes,
|
||||
//check if rpOne.nested[i] is
|
||||
//a subtype of rpOther.nested[i]:
|
||||
if (!(rpOther.nested[i] instanceof BindingPattern bpOther)) {
|
||||
continue NEXT_PATTERN;
|
||||
}
|
||||
if (rpOne.nested[i] instanceof BindingPattern bpOne) {
|
||||
if (!types.isSubtype(types.erasure(bpOne.type), types.erasure(bpOther.type))) {
|
||||
continue NEXT_PATTERN;
|
||||
}
|
||||
} else if (rpOne.nested[i] instanceof RecordPattern nestedRPOne) {
|
||||
if (!types.isSubtype(types.erasure(nestedRPOne.recordType()), types.erasure(bpOther.type))) {
|
||||
continue NEXT_PATTERN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8262891 8268871 8274363 8281100 8294670 8311038 8311815 8325215 8333169 8327368
|
||||
* @bug 8262891 8268871 8274363 8281100 8294670 8311038 8311815 8325215 8333169 8327368 8364991
|
||||
* @summary Check exhaustiveness of switches over sealed types.
|
||||
* @library /tools/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
@ -2182,6 +2182,66 @@ public class Exhaustiveness extends TestRunner {
|
||||
""");
|
||||
}
|
||||
|
||||
@Test //JDK-8364991
|
||||
public void testDifferentReductionPaths(Path base) throws Exception {
|
||||
doTest(base,
|
||||
new String[0],
|
||||
"""
|
||||
package test;
|
||||
public class Test {
|
||||
private int test(Root r) {
|
||||
return switch (r) {
|
||||
case Root(R1 _, _, _) -> 0;
|
||||
case Root(R2 _, R1 _, _) -> 0;
|
||||
case Root(R2 _, R2 _, R1 _) -> 0;
|
||||
case Root(R2 _, R2(R1 _, R1 _), R2(R1 _, R1 _)) -> 0;
|
||||
case Root(R2 _, R2(R1 _, R1 _), R2(R1 _, R2 _)) -> 0;
|
||||
case Root(R2 _, R2(R1 _, R1 _), R2(R2 _, R1 _)) -> 0;
|
||||
case Root(R2 _, R2(R1 _, R1 _), R2(R2 _, R2 _)) -> 0;
|
||||
case Root(R2 _, R2(R1 _, R2 _), R2(R1 _, R1 _)) -> 0;
|
||||
case Root(R2 _, R2(R1 _, R2 _), R2(R1 _, R2 _)) -> 0;
|
||||
case Root(R2 _, R2(R1 _, R2 _), R2(R2 _, R1 _)) -> 0;
|
||||
case Root(R2 _, R2(R1 _, R2 _), R2(R2 _, R2 _)) -> 0;
|
||||
case Root(R2 _, R2(R2 _, R1 _), R2(R1 _, R1 _)) -> 0;
|
||||
case Root(R2 _, R2(R2 _, R1 _), R2(R1 _, R2 _)) -> 0;
|
||||
case Root(R2 _, R2(R2 _, R1 _), R2(R2 _, R1 _)) -> 0;
|
||||
case Root(R2 _, R2(R2 _, R1 _), R2(R2 _, R2 _)) -> 0;
|
||||
case Root(R2 _, R2(R2 _, R2 _), R2(R1 _, R1 _)) -> 0;
|
||||
case Root(R2 _, R2(R2 _, R2 _), R2(R1 _, R2 _)) -> 0;
|
||||
case Root(R2 _, R2(R2 _, R2 _), R2(R2 _, R1 _)) -> 0;
|
||||
case Root(R2 _, R2(R2 _, R2 _), R2 _) -> 0; //functionally equivalent to: Root(R2 _, R2(R2 _, R2 _), R2(R2 _, R2 _))
|
||||
};
|
||||
}
|
||||
sealed interface Base {}
|
||||
record R1() implements Base {}
|
||||
record R2(Base b1, Base b2) implements Base {}
|
||||
record Root(Base b1, Base b2, Base b3) {}
|
||||
}
|
||||
""");
|
||||
}
|
||||
|
||||
@Test //JDK-8364991
|
||||
public void testX(Path base) throws Exception {
|
||||
doTest(base,
|
||||
new String[0],
|
||||
"""
|
||||
package test;
|
||||
public class Test {
|
||||
private int test(Root r) {
|
||||
return switch (r) {
|
||||
case Root(R2 _, R2(R1 _)) -> 0;
|
||||
case Root(R2(R1 _), R2(R2 _)) -> 0;
|
||||
case Root(R2(R2 _), R2 _) -> 0; //the above is functionally equivalent to: Root(R2(R2 _), R2(R2 _)) -> 0;
|
||||
};
|
||||
}
|
||||
sealed interface Base {}
|
||||
record R1() implements Base {}
|
||||
record R2(Base b) implements Base {}
|
||||
record Root(R2 b2, R2 b3) {}
|
||||
}
|
||||
""");
|
||||
}
|
||||
|
||||
private void doTest(Path base, String[] libraryCode, String testCode, String... expectedErrors) throws IOException {
|
||||
doTest(base, libraryCode, testCode, false, expectedErrors);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user