Skip to content

Cannot use final field of enum in constant expression. #50166

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

Closed
cyberail opened this issue Oct 9, 2022 · 4 comments
Closed

Cannot use final field of enum in constant expression. #50166

cyberail opened this issue Oct 9, 2022 · 4 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). type-question A question about expected behavior or functionality

Comments

@cyberail
Copy link

cyberail commented Oct 9, 2022

sdk version:
      sdk: ">=2.17.0 <3.0.0"
      Os = Linux

I am trying to use enhanced enums, inside the switch statement, interestingly enough I get an following error when using one of the final fields of the enum to check in switch statement:

Case expressions must be constant

My enum MsgType looks like the following:

enum MsgType {
  chatMsg('CHAT_MESSAGE'),
  session('SESSION'),
  ....
  ....
  someOtherMessage('SOME_OTHER_MESSAGE');
  
  const MsgType(this.name);

  final String name;

  @override
  String toString() {
    return name;
  }
}
switch (jsonMessage['type'] as String) {
      case MsgType.handUpIgnored.name:
        // do something here
        break;
        ....
        ....
      default:
        break;
    }

Error happens when checking for the name field, in switch statement.

@lrhn
Copy link
Member

lrhn commented Oct 9, 2022

This is expected behavior. The MsgType.handUpIgnored.name getter is not constant, so you cannot use it where a constant expression is needed.

@cyberail
Copy link
Author

This is expected behavior. The MsgType.handUpIgnored.name getter is not constant, so you cannot use it where a constant expression is needed.

But it comes from the constant class. And it is a final.

@lrhn
Copy link
Member

lrhn commented Oct 10, 2022

Making final fields of "constant classes" (classes with a constant constructor) be readable as constants when used in an otherwise constant expression looks reasonable.

The problem is that it breaks getter/field symmetry. The author of the class didn't explicitly choose to make that field usable in constant expressions, which means that they might choose to change the field to a getter in a later version of the same class. (Or in a subclass, but at least that does not affect enums, not unless we choose to allow enum values to add or override methods. That has been requested, and Java allows it for similar enums.)

If the author changes the field to a getter, then the code expecting to use the field as a constant will break.
So if constant class final fields where "constant" automatically, the class author would have to make a private field with a public getter to avoid being locked into the field being constant.

But changing a field to a getter should be a safe refactoring, that's one of the points of having getters/setters that act precisely like fields to begin with. And avoiding the private-field/public-getter-setter of Java was another goal.

Now, if the class author could declare the field explicitly const (or something similar), thereby opting in to it being usable in constant expressions, then they'd have opted in to it being breaking to change it. We do not have that feature. (And if we did, we'd probably have to consider a way of making constant getters too. Something like dart-lang/language#1518.) But we don't have that, so you can't use any getters in constant expressions, other than String.length.

@lrhn lrhn added type-question A question about expected behavior or functionality area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Oct 10, 2022
@lrhn lrhn changed the title Create an issue Cannot use final field of enum in constant expression. Oct 10, 2022
@mraleph
Copy link
Member

mraleph commented Oct 19, 2022

I am going to close this - given that the question is answer and improvements are tracked in a separate issue.

@mraleph mraleph closed this as completed Oct 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). type-question A question about expected behavior or functionality
Projects
None yet
Development

No branches or pull requests

3 participants