> On Aug 20, 2020, at 4:14 PM, Brian Goetz <brian.go...@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.

Reply via email to