Skip to content

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

Closed
@tlarsen4google

Description

@tlarsen4google

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}) {
                      ^

Activity

iposva-google

iposva-google commented on Apr 23, 2014

@iposva-google
Contributor

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

gbracha

gbracha commented on Apr 23, 2014

@gbracha
Contributor

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

lrhn commented on Apr 23, 2014

@lrhn
Member

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

gbracha commented on Apr 23, 2014

@gbracha
Contributor

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

DartBot

DartBot commented on Apr 24, 2014

@DartBot

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

DartBot commented on May 5, 2014

@DartBot

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

DartBot commented on May 5, 2014

@DartBot

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

DartBot commented on May 5, 2014

@DartBot

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

DartBot commented on May 5, 2014

@DartBot

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

floitschG commented on Aug 19, 2014

@floitschG
Contributor

Issue #20574 has been merged into this issue.

lrhn

lrhn commented on Nov 18, 2014

@lrhn
Member

Issue #21625 has been merged into this issue.

munificent

munificent commented on Dec 15, 2016

@munificent
Member

Duplicate of #3059.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area-languageDart language related items (some items might be better tracked at github.com/dart-lang/language).closed-duplicateClosed in favor of an existing reporttype-enhancementA request for a change that isn't a bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @kevmoo@munificent@gbracha@lrhn@iposva-google

      Issue actions

        Constant-indexed expression of a const List or Map should be a compile-time const. · Issue #18389 · dart-lang/sdk