Implicit switch exceptions (was: [switch] Status of implementation of switch expression)

Brian Goetz brian.goetz at oracle.com
Tue Feb 27 22:33:18 UTC 2018



On 2/27/2018 5:23 PM, John Rose wrote:
> On Feb 27, 2018, at 1:30 PM, Brian Goetz <brian.goetz at oracle.com 
> <mailto:brian.goetz at oracle.com>> wrote:
>>
>> (Some have questioned whether inserting the throwing default 
>> automatically is wise, but I like the fact that it amounts to an 
>> assertion that "these are all the enum constants in type E", and 
>> getting an exception when that assumption is seen to be violated.)
>
> +100 the exception is the right response to an event at runtime that
> was not supposed to happen at compile time.

THe alternative is the status quo; make the user declare a default (that 
presumably throws an AssertionError, and probably with a less 
informative message than the compiler would provide, because the user is 
already annoyed they have to write this code.)

> (I assume the user
> *must* mention all the enums present statically at compile time,
> right?)

Right.  An expression switch must be exhaustive; switching over all the 
known constants of an enum is considered exhaustive.  Any switch with a 
default is considered exhaustive.  We have more fun in store for us to 
reason about other forms of exhaustiveness as our patterns get more 
interesting.

> Meanwhile, if there is a dynamic data-dependent condition
> which is thought to be unlikely but must be reported with an
> exception, we often use a RuntimeException, such as NPE,
> CCE, ASE, IAE.  Note that EnumConstantNotPresentException,
> is thrown by annotation processing.

Heh, didn't know about ECNPE; might well be good enough to reuse for 
now.  Certainly clear enough; you had a switch without a default where 
the desired Enum Constant is Not Present in your switch, which is an 
Exception.  But as you point out later, there will be other forms of 
switches that looked exhaustive at compile time (switching over all 
types in a sum type) and are not at runtime (someone added one).  
Whether we want the same exception in both cases, or a situationally 
specific one like ECNPE, is open to discussion.

I too prefer an RE to an Error.

> If we could prove that all such incomplete switches are
> the results of sihfts to API hierarchies after static compilation,
> that would be an argument in favor of ICCE.

The problem with ICCE is that adding an enum constant is *not* 
incompatible (the way removing one is); it's just that the code embodies 
an assumption which this change breaks.  So ICCE feels too strong, and 
too low-level, here.

> Bottom line:  unless we can tie switch coverage errors closely
> to API structure, I think we need a new RE named, roughly,
> SwitchDefaultNotFoundException.
>

Scala uses MatchError (extends RuntimeException) for this.




More information about the amber-dev mailing list