dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.2k stars 1.57k forks source link

Allow const instance fields as const expressions on const objects. #16547

Open lrhn opened 10 years ago

lrhn commented 10 years ago

We currently disallow const on instance fields because we don't have a good semantics for them.

Consider allowing

class C {
  const int foo;
  const C(this.foo);
}

The instance const field will act just as a final field, except when initialized by a const invocation of a const constructor (i.e., except when on an actual compile-time constant).

Then we can allow expressions like x.foo to be compile time constant expressions if x is a compile time constant expression with a value that has a const instance field named foo.

This will allow changing a static-only class to an object, and still expose the same compile time constants.

Other uses could be an enum implementation that assigns a unique id to each enum object, and then allowing switching on the id instead of on the object by writing case FOO.id:.

This breaks the field/getter symmetry, so perhaps we can also allow:

const get x => <potential instance compile time constant expression>

where the expression must be a compile time constant expression potentially containing this.x references to const fields (just as potential const expressions in constructors can refer to const constructor parameters).

gbracha commented 10 years ago

It looks like it would all work, though I am loath to complicate const and/or getters any further.


Set owner to @gbracha. Added Accepted label.

DartBot commented 10 years ago

This comment was originally written by @seaneagan


Yes, const is currently pretty complicated. But the thing that's complicated about it is all the restrictions and special cases about what can and cannot be const. The goal should be to remove the restrictions and special cases from the language by allowing constants to be defined as much as possible at the library level. See issue #18241 for a more comprehensive approach.

DartBot commented 9 years ago

This comment was originally written by @zoechi


It looks like this is the error I run into with this code

class SomeEnum {   static const SomeEnum FIRST = const SomeEnum._(1, 'FIRST');

  static const List<SomeEnum> values = const <SomeEnum> [FIRST,];

  final value;   final name;   const SomeEnum._(this.value, this.name); }

void main() {   const x = SomeEnum.FIRST.name; // <= 'const' variables must be a const value }