> From: "Jesper Steen Møller" <jes...@selskabet.org> > To: "Remi Forax" <fo...@univ-mlv.fr>, "Ilyas Selimov" > <ilyas.seli...@jetbrains.com> > Cc: "compiler-dev" <compiler-...@openjdk.java.net> > Sent: Vendredi 3 Septembre 2021 10:30:58 > Subject: Re: Dominance in pattern matching for switch: Spec and Javac > inconsistency
> Hi Hi, moved to spec-expert because there is an open question at the end, > If I understand correctly, a guarded switch label effectively can't dominate > any > other labels, since the spec doesn't go into trying to statically analyze > whether or not the guard could ever be false. > I guess the spec could mention that (but it would be a comment, since it > follows > from the other rules). A guarded switch pattern can not dominate any other guarded switch pattern that have the same type pattern prefix, e.g. case Integer i && foo(i) vs case Integer i && bar(i) but a guarded switch dominates it's prefix, e.eg case Integer i && foo(i) dominates case Integer. But there is no rule between a guarded pattern like case Integer i && foo(i) and case 1, so they can appear in any order. We may want to revisit that because from my own experience, it's not rare to add/remove guards to a pattern during the development, so forcing case 1 to dominate case Integer i && foo(i) means that you do not have to re-organize the case when you remove the guard. But I don't know if it's a good idea or not ? > -Jesper Rémi >> On 3 Sep 2021, at 09.29, Remi Forax < [ mailto:fo...@univ-mlv.fr | >> fo...@univ-mlv.fr ] > wrote: >>> From: "Ilyas Selimov" < [ mailto:ilyas.seli...@jetbrains.com | >>> ilyas.seli...@jetbrains.com ] > >>> To: "compiler-dev" < [ mailto:compiler-...@openjdk.java.net | >>> compiler-...@openjdk.java.net ] > >>> Sent: Vendredi 3 Septembre 2021 07:27:42 >>> Subject: Dominance in pattern matching for switch: Spec and Javac >>> inconsistency >>> Hello! >>> The next code compiles correctly, but it seems to contradict the dominance >>> rules: >>> void test(Integer i) { >>> switch (i) { >>> case Integer in && in != null: >>> break; >>> case 1: >>> break; >>> case default: >>> break; >>> } >>> } >>>> A switch label that has a pattern case label element p dominates another >>>> switch >>>> label that has a constant case label element c if either of the following >>>> is >>> > true: >>>> - the type of c is a primitive type and its wrapper class (5.1.7) is a >>>> subtype >>> > of the erasure of the type of p. >>> Maybe the type of p should also be total for the type of selector expression >>> like in the rules for pattern-over-null dominance? >> For me, the problem comes from the guard, if you write the same code without >> the >> guard, the compiler correctly emits an error >> void test(Integer i) { >> switch (i) { >> case Integer in: >> break; >> case 1: >> break; >> case default: >> break; >> } >> } >> for me, this rule should apply even if p is a guard, the type of p when p is >> a >> guard is the type of the type part (the left part) of a guard. >> So it's more a bug in the implementation than a spec issue. >> But given that Eclipse has the same issue, the spec should be clarified. >>> Thanks, >>> Ilyas >> regards, >> Rémi