Skip to content

Constant-indexed expression of a const List or Map should be a compile-time const. #18389

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
tlarsen4google opened this issue Apr 22, 2014 · 12 comments
Assignees
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-duplicate Closed in favor of an existing report type-enhancement A request for a change that isn't a bug

Comments

@tlarsen4google
Copy link

If a Map or List is const, and a constant, present key or constant, in-bounds index is used, the resulting expression should also be a compile-time constant.

What steps will reproduce the problem?

const Map<String, String> A_CONST_MAP = const {
  'foo': 'bar',
  'baz': 'bif',
};

const List<String> A_CONST_LIST = const ['foo', 'bar'];

const String A_CONST_STRING = A_CONST_MAP['foo'];
const String ANOTHER_CONST_STRING = A_CONST_LIST[0];
const String YET_ANOTHER_CONST_STRING = A_CONST_MAP[A_CONST_LIST[0]];

What is the expected output?

No compiler error.

What do you see instead?

error: line XX pos YY: initializer is not a valid compile-time constant
const String A_CONST_STRING = A_CONST_MAP['foo'];
                              ^

error: line XX pos YY: initializer is not a valid compile-time constant
const String ANOTHER_CONST_STRING = A_CONST_LIST[0];
                                    ^
etc.

What version of the product are you using? On what operating system?

Dart VM version: 1.1.0-dev.5.11 (Wed Jan 15 00:41:27 2014) on "linux_x64"

Please provide any additional information below.

Declaring these "final" quiets the "initializer is not a valid compile-time constant" error:

final String aFinalString = A_CONST_MAP['foo'];
final String anotherFinalString = A_CONST_LIST[0];

However, the resulting Strings are then not usable as default values for named parameters:

error: line XX pos YY: expression is not a valid compile-time constant
void Foo({String val: aFinalString}) {
                      ^

@iposva-google
Copy link
Contributor

cc @gbracha.
Removed Type-Defect label.
Added Type-Enhancement, Area-Language, Triaged labels.

@gbracha
Copy link
Contributor

gbracha commented Apr 23, 2014

This sounds reasonable. Changing the spec has recently become much harder, because of the standardization process. It might make into the next rev of the Dart standard.


Set owner to @gbracha.
Added Accepted label.

@lrhn
Copy link
Member

lrhn commented Apr 23, 2014

A final field of a const object could also be read/determined at compile time. Would that be possible too? (Or maybe just a special case for String.length/List.length?)

@gbracha
Copy link
Contributor

gbracha commented Apr 23, 2014

Re #­3: this makes the final vs. const distinction a bit murky, but it is certainly possible.

@DartBot
Copy link

DartBot commented Apr 24, 2014

This comment was originally written by @seaneagan


Re #­3/#­4: You should be required to mark the instance field as "const" instead of "final" for that behavior. This is because the constness makes refactoring to a getter a breaking change since getters can't be const. It must be opt in, just like constructors and static fields must be marked as "const". The instance field would only be const if the constructor was called with "const".

However, getters could also be const with issue #1.

@DartBot
Copy link

DartBot commented May 5, 2014

This comment was originally written by da...@google.com


Would also like to see using a final member of a static const object as a const

class Foo {

  final int value;

  static const Foo BAR = const Foo.(1);
  static const Foo BAZ = const Foo.
(2);

  const Foo._(this.value);
}

...

switch (x) {

  case Foo.BAR.value:
    ...
    break;

  case Foo.BAZ.value:
    ...
    break;
}

@DartBot
Copy link

DartBot commented May 5, 2014

This comment was originally written by sophielight...@gmail.com


#­7: see #­5 for why it should be const int value for it to be considered constant.

@DartBot
Copy link

DartBot commented May 5, 2014

This comment was originally written by da...@google.com


#­8: That's would work, but it's not possible to mark a field in a class const at this point (only static const, which isn't useful here).

This change might be implied in issue #1, but that's not clear from a cursory read, hence this comment.

@DartBot
Copy link

DartBot commented May 5, 2014

This comment was originally written by @seaneagan


I noted in issue #18241 that const instance fields (and operators like List.[] as above) would be some of the methods that could be marked "const".

@floitschG
Copy link
Contributor

Issue #20574 has been merged into this issue.

@lrhn
Copy link
Member

lrhn commented Nov 18, 2014

Issue #21625 has been merged into this issue.

@tlarsen4google tlarsen4google added Type-Enhancement area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Nov 18, 2014
@kevmoo kevmoo added type-enhancement A request for a change that isn't a bug and removed priority-unassigned labels Feb 29, 2016
@munificent
Copy link
Member

munificent commented Dec 15, 2016

Duplicate of #3059.

@munificent munificent added the closed-duplicate Closed in favor of an existing report label Dec 15, 2016
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). closed-duplicate Closed in favor of an existing report type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

8 participants