On Fri, 21 Apr 2023 15:17:37 GMT, Maurizio Cimadamore <mcimadam...@openjdk.org> wrote:
>> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java line 915: >> >>> 913: */ >>> 914: private List<PatternDescription> reduceBindingPatterns(Type >>> selectorType, List<PatternDescription> patterns) { >>> 915: Set<Symbol> existingBindings = patterns.stream() >> >> Playing some more - I found this example: >> >> >> class Test { >> sealed interface I permits C, D { } >> non-sealed interface C extends I { } >> non-sealed interface D extends I { } >> >> interface F { } >> >> <Z extends I & F> int test(Z o) { >> return switch (o) { >> case C c -> 1; >> case D d -> 2; >> }; >> } >> } >> >> >> Which compiles correctly, but it doesn't look exhaustive to me (because of >> F) ? > > Also, surprisingly, if I make C and D classes (instead of interfaces): > > class Test { > sealed interface I permits C, D { } > final class C implements I { } > final class D implements I { } > > interface F { } > > <Z extends I & F> int test(Z o) { > return switch (o) { > case C c -> 1; > case D d -> 2; > }; > } > } > > I get errors like: > > > Foo.java:10: error: incompatible types: Z cannot be converted to Test.C > case C c -> 1; > ^ > where Z is a type-variable: > Z extends I,F declared in method <Z>test(Z) > > > Which seems odd? Nevermind - these issues are due to a misunderstanding of the rules with intersection types - e.g. given A & B, if a pattern covers _any_ of A, B, then it covers A & B. Similarly, the second issue I reported is in reality caused by the fact that in the snippet with `class`, I also added `final` which then makes I & F a type with no concrete witnesses (so cast will always fail from there to either C/D). ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/13074#discussion_r1173912165