Pattern Matching for switch (Second Preview)
Brian Goetz
brian.goetz at oracle.com
Wed Sep 22 19:25:42 UTC 2021
I have several things I'd like to see make it into this round.
1. Totality for GADTs. If we have a hierarchy:
sealed interface Foo<T> { }
class A<T> implements Foo<T> { }
class B<T> implements Foo<T> { }
class C implements Foo<String> { }
then when switching over a Foo<String>, we need all of A/B/C to be
total, but when switching over a Foo<Shoe>, we only need cover A and B
in order to be total, because C is not a possible choice. When
considering totality, we should only consider the options whose
parameterizations are consistent with that of the target.
2. Inference for type patterns. This one may be a little
controversial, because we already let this ship sail with type patterns
in instanceof, but I'm pretty convinced that what we're doing right now
is wrong. Currently, if we are switching on a List<String>, we disallow
a type pattern for ArrayList<Frog>, because this would require an
unchecked conversion. This is right. But if we have a `case ArrayList
a`, the type of `a` is not ArrayList<String>, but raw ArrayList. This
is almost always not what the user wants; there's no migration
compatibility here where the switch target was generified but the case
labels are not. Like we do with method references, we should infer a
reasonable parameterization of ArrayList from the match target when a
"naked" type shows up in a type pattern. (If the user really wants a
raw ArrayList, they can switch on a raw List.)
Fixing this for switch is no problem, as it is in preview, but fixing
this in instanceof requires more care, since there may be production
code out there. However, we've generally held that it is OK to infer
_more_ specific types than have previously been inferred; I doubt much
code would be impacted -- more likely, some silly casts would go away,
since users no longer have to cast to ArrayList<String>.
3. Also, Dan raised a coverage question here:
https://mail.openjdk.java.net/pipermail/amber-spec-experts/2021-July/003049.html
In this example (asterisk means abstract):
A* = B1* | B2* | C*
B1* = D1
B2* = D2
C* = D1 | D2
In order to cover A, we need to cover B1|B2|C. Given
case B1:
case B2:
B1 and B2 are clearly covered; the question is C. And C=D1|D2. B1
covers D1, and B2 covers D2, so B1|B2 covers D1|D2, and therefore B1|B2
covers C.
On 9/22/2021 12:11 PM, Jan Lahoda wrote:
> Hi,
>
> There is a new draft JEP for preview 2 of Pattern Matching for switch
> here:
> https://bugs.openjdk.java.net/browse/JDK-8273326
>
> The exact changes that will be done under this round of preview are
> yet to be determined, but changes related to generics handling in
> pattern matching switches seem to be plausible.
>
> Feedback is welcome!
>
> Thanks,
> Jan
>
More information about the amber-dev
mailing list