[pattern-switch] Exhaustiveness

Dan Smith daniel.smith at oracle.com
Sat Aug 29 00:34:41 UTC 2020


> On Aug 20, 2020, at 4:14 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> 
> If a user had:
> 
>     case Box(Head)
>     case Box(Tail)
> 
> and a Box(null) arrived unexpectedly at the switch, would NPE really be what they expect?  An NPE happens when you _dereference_ a null.  But no one is deferencing anything here; it's just that Box(null) fell into that middle space of "well, you didn't really cover it, but it's such a silly case that I didn't want to make you cover it either, but here we are and we have to do something."  So maybe want some sort of SillyCaseException (perhaps with a less silly name) for at least the null residue.  

So the idea being pursued on this thread is that:

case Box(Head)
case Box(Tail)

implies an implicit

case Box(null): throw [something];

But I want to point out that you also said:

> If we have:
> 
>     case Box(Rect r)
>     case Box(Circle c)
>     case Bag(Rect r)
>     case Bag(Circle c)
>     default
> 
> then Box(Pentagon|null) and Bag(Pentagon|null) clearly fall into the default case, so no special handling is needed there.

So whether to insert 'case Box(null)' immediately after 'case Box(Tail)' depends on whether there's a downstream handler for 'Box(null)'. That's a pretty complex and non-local user model.

And for all this complex analysis we get... some different exception types? Doesn't seem like a worthwhile trade.

Separately, I don't love that we're using ICCE for an unmatched enum—an error which typically indicates a binary incompatibility. We don't (and should not) say in JLS 13.4.26 that adding an enum constant is a binary incompatible change. Enum constants add new cases all the time.

What I'd like to do instead: switch expressions that are optimistically/weakly total get an implicit 'default' case that throws 'UnmatchedSwitchException' or something like that for *everything* that goes unhandled. Exactly what diagnostic information we choose to put in the exception is a quality of implementation issue. As a special case, if the unmatched value is 'null' (not 'Box(null)'), we *might* decide to throw an NPE instead (depending on how your ideas about null hostility in switches pan out).

This is a behavioral change for enum switch expressions in Java 14+ code, which makes me feel a bit sheepish, but I don't think anybody will mind a change now that the design has evolved enough to recognize the need for a specific exception class.



More information about the amber-spec-experts mailing list