Make all switches exhaustive?

Remi Forax forax at
Tue Apr 27 17:47:27 UTC 2021

> De: "Brian Goetz" <brian.goetz at>
> À: "amber-spec-experts" <amber-spec-experts at>
> Envoyé: Mardi 27 Avril 2021 19:11:18
> Objet: Make all switches exhaustive?

> 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.
This will not solve the problem of Maurizio for sub-patterns but i like it. 

We don't have to later transform the warning to an error, keeping it as a warning can be annoying enough to force people to change their code (or ALT-ENTER + CTRL+1 ont it). 

> 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;
"default:" should be enough no ? 

> 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?)
I think we should tackle "default" not being at the end the same way. 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the amber-spec-experts mailing list