Re: Question about pattern matching and sealed types – redundant switch cases

Brian Goetz brian.goetz at oracle.com
Sat Apr 19 17:19:30 UTC 2025


It's not as bad as you say, but the answer is still the same :)

It is possible to do flow-specific refinement without actually changing 
how we track the type.  So it would be possible to say that the type of 
myVar is still A, while maintaining a lattice of type 
inclusion/exclusion refinements that would not actually change semantics 
(such as method overload selection), but could be used to detect 
unreachable code.

But the return on that effort seems pretty squarely in the "there are 
much better things we could work on" bucket.

On 4/19/2025 1:08 PM, Remi Forax wrote:
>
>
> ------------------------------------------------------------------------
>
>     *From: *"Andreas Berheim Brudin" <andreas.brudin at gmail.com>
>     *To: *"amber-dev" <amber-dev at openjdk.org>
>     *Sent: *Saturday, April 19, 2025 6:17:43 PM
>     *Subject: *Question about pattern matching and sealed types –
>     redundant switch cases
>
>     Hi all,
>
>     I'm new to the list—apologies if this has been discussed before,
>     and thanks in advance for your time.
>
>     I have a question about pattern matching with sealed types.
>     Consider this example:
>
>     sealed interface A permits B, C {}
>     record B(String b1, String b2) implements A {}
>     record C(String c) implements A {}
>
>     A myVar = ...;
>     if (!(myVar instanceof B(var b1, var b2))) {
>         return switch (myVar) {
>             case C(var c) -> c;
>             case B b -> throw new IllegalStateException("should not
>     happen");
>         };
>     }
>     // use b1, b2
>
>     Here, I want to keep an early-return style, but since I need to
>     return a value from C, I have to use a switch. This leads to
>     redundancy: we've already tested myVar is not a B, so that case
>     should be statically unreachable.
>
>     My questions:
>
>     1. Is there any consideration or ongoing work to allow the
>     compiler to automatically eliminate such unreachable cases?
>
>
> The short answer is no :)
>
> Long answer,
>   (1) myVar does not change its type, it is declared as an A, it 
> always be an A (Groovy or Kotlin behave differently, they use flow typing)
>   (2) the type system of Java has no notion of exclusion, the type A 
> but not B does not exist
>   (3) instanceof and switch does not have the same semantics, 
> instanceof has no notion of exhaustiveness while a switch on a sealed 
> type has.
>
> so because of (1) the type of myVar can not be changed, because of (2) 
> its new type inside the if can not be "A but not B" and because of (3) 
> the new type can not be only C.
>
>
>
>     2. If only one case remains (in this case, C), could it be
>     possible to treat the variable as a C directly without requiring
>     an explicit switch?
>
>
> No,
>
>
>
>     Again, apologies if this has already been discussed. I'd
>     appreciate any pointers to relevant threads or JEPs if so.
>
>
> The relevant JEPs are JEP 394 (for instanceof) and 441 (for switch).
>
>
>
>     Thanks,
>     Andreas
>
>
> regards,
> Rémi
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20250419/8e0175c6/attachment-0001.htm>


More information about the amber-dev mailing list