Maurizio's comment got me thinking about a possible way to eliminate the sharp edge of "sometimes switches are type-checked for exhaustiveness, and sometimes not."

Historically, there is no requirement that switches be exhaustive; legacy switches without a default are like unbalanced ifs.  (Notably, though, the DA rules do distinguish between switches with and without a default, and switches implicitly reject any null remainder -- so we still do have a solid base to build on here.)

When we did expression switches, we said "expression switches must be total."  This was a forced move if we wanted to reuse "switch", because expressions must be total and compatibility backed us into letting statement switches be partial. Unfortunately, this leaves statement switches with less type checking than expression switches, since there is no way to even opt into exhaustiveness checking.

As switch gets more powerful (e.g., switching over sealed types with patterns), this lack of exhaustiveness checking becomes a bigger deal.  We'd been imagining that we'd have to "patch" switch to allow opting into exhaustiveness checking, but maybe there's another way.

As we are about to dramatically extend the power of switch (by permitting pattern labels, and allowing switches on other types than integers, boxes, strings, and enums), what we could do is:

 - Erroring on non-exhaustive non-legacy statement switches now;
 - Warning on non-exhaustive legacy statement switches now;
 - Later upgrading these warnings to errors, after a period of time where people can update their code.

The world we end up in in the long run is: all switches are exhaustive, with no new language surface for managing exhaustiveness.

Legacy switches are those whose operand type is one of the "classic" types and all labels are constant labels or "default".

For a switch that is deliberately non-exhaustive, all the user has to do to capture this (and shut up the compiler) is:

    default: break;

which is not very intrusive, and arguably makes the code more readable anyway.  Users will see a speed bump when upgrading to pattern switches (clippy will tell them "I see you're writing a pattern switch, don't forget to end it with default:break") which presumably they will quickly internalize.

(How's that for teaching an old dog new tricks?)

Reply via email to