> De: "Brian Goetz" <brian.go...@oracle.com> > À: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > 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. Rémi