-
Notifications
You must be signed in to change notification settings - Fork 213
Make it possible to mark an enum as "extensible" #2968
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This was a warning previously (or some sort of diagnostic at least), which was good because you would at least be notified when some new value was added, where the Is there a way we can retain that behavior as well? |
The "obvious" syntax would be An alternative is to not use final class MyEnumLikeThing {
v1(1), v2(2), v3(3); // <- new!
final int value;
const MyEnumLikeThing(this.value);
} The canonical values list is what makes an It's ... not a convenient syntax, though. Probably too hard to parse without a lot of look-ahead. So maybe allow you to write final enum class MyEnumLikeThing {
v1._(1),
v2._(2),
v3._(3);
final int value;
const MyEnumLikeThing._(this.value);
} If we think the primary/only use-case is to create non-exhaustive enum-like value sets, the analyzer could choose to give hints if a switch over the instances isn't complete. But that might just prevent other reasonable uses. |
For switch expressions, a default case will have to be added no matter what. For switch statements, do you want users to have a default case (possibly that throws), or are you comfortable with them falling off the end when you add a value to the enum. I wonder whether the nicest thing to do here might not just be: enum Foo {
a,
b,
_reservedForFutureCases
} Which will force all switch expressions and statements to have a default case for this type. |
Personally I would prefer that they have a default case, which was why I proposed that extensible enums would still be considered "always exhaustive" types. But I don't feel too strongly about this particular detail of the proposal.
Oh, that's clever! I will mention this to the analyzer team 😃. |
(Based on a discussion with the analyzer team this morning)
In Dart 3.0, with the addition of support for patterns, it has become a compile-time error if the scrutinee of a switch has an enum type, and the switch isn't exhaustive. This means that if a package publishes an enum type as part of its public API, adding a value to that enum is a breaking change.
(Previous to Dart 3.0, it was still technically breaking, however the breakage scenario was less common: a problem would only occur if the new enum value opened up a control flow path that triggered some other compile-time error. For example, adding the new enum value might have prevented a function from returning a value, or prevented a local variable from being definitely assigned.)
Some package authors want to be able to add values to existing public enums without breaking clients, for example the analyzer team would like to be able to add values to the meta package's TargetKind enum without having to do a major version bump. Currently they're considering changing the enum to a class with static constant fields, so that switches on
TargetKind
will no longer be required to be exhaustive (based on a suggestion from @lrhn).It would be nice if instead there were some way to tell the compiler that a certain enum is "extensible". We might do this, for example, with a keyword, e.g.:
or perhaps the
...
symbol could be used to indicate that more enum values are likely to be added in the future, i.e.:Making an enum extensible would suppress the logic in the exhaustiveness algorithm that allows a switch to be exhaustive if it mentions all possible enum values. However, the enum would still be considered an "always exhastive" type. That means that switches would be required to include either a default case or a case that matches the enum using
_
. For example, this would become a compile-time error:And the client would have to do something like this instead:
CC @dart-lang/language-team
The text was updated successfully, but these errors were encountered: