merging cases in between values and types

forax at univ-mlv.fr forax at univ-mlv.fr
Wed Sep 15 16:06:02 UTC 2021


----- Original Message -----
> From: "Gavin Bierman" <gavin.bierman at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Sent: Lundi 13 Septembre 2021 17:00:09
> Subject: Re: merging cases in between values and types

> Hi Remi,

Hi Gavin,

> 
> Sorry for the slow reply:
> 
>> On 8 Sep 2021, at 07:42, Remi Forax <forax at univ-mlv.fr> wrote:
>> 
>> Hi all,
>> the current spec support merging/fallthrough cases only when there is a case
>> null,
>> like
>>  case null, case Integer i -> // i can use 'i' here
>> 
>> First, i'm not sure it's clearly written in the spec, i was not able to pinpoint
>> the rule allowing it.
> 
> In 14.11.1 there is a bunch of well-formedness conditions listed for switch
> labels. The paragraph begins “For every switch label in a switch block, all of
> the following must be true, otherwise a compile-time error occurs…” What
> follows is a bunch of rules that spell out which switch labels are correctly
> formed, and which are not. The two rules that cover your question here are:
> 
> 
> • If a switch label has a constant case label element then if the switch label
> also has other case element labels they must be either a constant case label
> element, the default case label element, or the null case label element.
> 
> and
> 
> • If a switch label has a null case label element then if the switch label also
> has any pattern case element labels, they must be type patterns (14.30.1).


Thanks, i've overlook the rules of 14.11.1.

The last point treat null has a special value, and i'm proposing to extend that rule to any constant not just null,
because i don't see why null is a special case (sorry) here.

This rule works because the type of null is a subtype of all the types.
But we know that while this is true now, it will not be true in the future when we will introduce the primitive class.

So instead of adding a special rule for null now to specialize it again when Valhalla step 1 lands,
i think it's better to stick with a more general rule that say that you can have a case with a constant with a case with a type pattern (or a guard that starts with that type pattern) if the type of the constant is a subtype of the type of the type pattern.

This will work with
  case null, Integer i:
  case "foo", String s && ...:
and will not allow
  case null, APrimitiveClass apc:
in the future.

> 
> 
> So the first rule forbids you from writing case 42, Integer i. The second rule
> allows you to say case null, Integer i (and case Integer i, null actually.)
> 
> So, yes, the null is treated specially. Indeed it’s behaviour is NOT about fall
> through really. When you write case null, Foo f you are not asking for the type
> pattern test to be carried out if the value is null (it might fail!). Nor are
> you asking for it to be ignored (cos then the pattern variable will not be
> initialised). You’re actually saying “if it’s null then it matches AND the
> variable i is initialised to null”. So it’s being treated like a special
> pattern label. If we were to give it an alternative syntax, we might write
> “case Foo? f” instead of “case null, Foo f”.
> 
> Hope this helps,
> 
> Gavin

regards,
Rémi

> 
> 
>> Then i wonder if this special behavior is special because null is special or if
>> it should work with any values of the type of the type pattern,
>> i.e. it works because null is a possible value of Integer, in that case, it
>> should also work with any other values like 42
>> 
>>  case 42, case Integer i ->  // i can use 'i' here
>> 
>> So is null a special value or does this rule also work with any values.
>> 
>> regards,
>> Rémi
>> 


More information about the amber-spec-experts mailing list