[External] : Re: RFR: 8291769: Translation of switch with record patterns could be improved

forax at univ-mlv.fr forax at univ-mlv.fr
Sun Aug 7 08:14:20 UTC 2022


[...] 

>>> Situation would, of course, be different if we tried to optimize not
>>> only prefixes of the patterns - but this does not seem to be the
>>> proposal in switch-pattern-combinator.

>>> As for casting to the last permitted type - I don't see how this relates
>>> to decision trees.  While casting and catching might look interesting
>>> from the bytecode perspective, it is something that is likely to be
>>> relatively complex to implement in javac, and using an (effective)
>>> instanceof and an explicit fallback does not really sound terrible.

>> The idea of using a cast is that you provide a good error message to the users
>> because the ClassCastException stores the class that is not handled by the
>> pattern matching.
>> You loose that information if you use an explicit fallback.

> Sorry, but if I understand what you are proposing is:

> B b = (B) obj; //magical catch handler somewhere handling the CCE

> $rest$;

> what I am saying is that this can be achieved by an analog of:

> if (obj instanceof B b) {

> $rest$;

> } else {

> throw <an-exception-we-want>(obj.getClass());

> }

> What information is lost?
sorry I misunderstood you. 
There is no information lost in this case, the generated bytecodes is just bigger which one one reason cited by Brian to only throw once in the fallback case. 

Nitpicking, "null" is treated differently so the code should be 

if (obj == null) { 
throw NPE; 
} 

if (obj instanceof B b) { 

$rest$; 

} else { 

throw <an-exception-we-want>(obj.getClass()); 

} 

Using a cast also has an issue with null but the NPE can be thrown implicitly if the sub-pattern is a record (something you know locally for each node of the decision tree). 

>>> There is also a question on when this is safe to do - if there's a `case
>>> Object o` at the end of the switch, then probably this is not correct to
>>> do anyway, etc.

>> It is safe to do if the compiler has type-checked the patterns before, the cast
>> is only done in case of a sealed type, not if there is a common supertype at
>> the end.

> I mean - consider:

> sealed interface I {}

> final class OnlySubtypeAtCompileTime implements I {}

> record Box(I i) {}

> Object b = new Box(<a-new-subtype-not-known-at-compile-time>);

> switch (b) {

> case Box(OnlySubtypeAtCompileTime t) -> System.err.println("Should probably not
> fail here,");

> case Object obj -> System.err.println("but should end up here.");

> }
I think we are agreeing here that in this case, using a cast instead of an instanceof is a mistake. We only need the cast in case if there is a sealed type and no fallback, this information has flow from the type-ckecking. 

Rémi 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20220807/924682c3/attachment-0001.htm>


More information about the compiler-dev mailing list