dart-lang / dart-lang/language
`const` Constructor parameters are never considered `const`
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
If a class defines a `const` constructor, it can be created either as `const` or as regular internally `final` object.
Should this `const-in-const-context` notion not apply to the parameters as well?
Take e.g.:
```dart
class CanConst {
final int value;
const CanConst(this.value);
}
```
Here `const v = 1; const CanConst(1)` works but `(int v) => const CanConst(v);` does not.
=> parameter must be constant when used in constant context.
Where as `const v = 1; CanConst(1)` and `(int v) => CanConst(v);` both work.
=> parameter must not be constant when used outside constant context.
==> parameter behaves like it is `const-in-const-context`
______
Since the parameter is currently not `const-in-const-context`, we get e.g. the following:
```dart
const canConst = CanConst(1);
const canNotConst = CanNotConst(1); // Error
const canNotConstContainer = CanNotConstContainer(CanNotConst(1)); // Error
class CanConst {
final int value;
const CanConst(this.value);
}
class CanNotConst {
final int value;
CanNotConst(this.value);
}
class CanNotConstContainer {
final CanNotConst cnc;
const CanNotConstContainer(this.cnc); // No Error
}
```
Which I think should be warned about in `const CanNotConstContainer(this.cnc)` since `CanNotConst` will never be able to be `const`.
_________
Further, we get counter-intuitive (at least to me) behaviour with trying to make classes constant:
Starting with this non-constant class:
```dart
class MyClass {
final int value;
final MyOtherClass other;
MyClass(this.value, this.other);
MyClass.sameOther(int value)
: this.value = value,
other = MyOtherClass(value);
}
class MyOtherClass {
final in value;
const MyOtherClass(this.value);
}
```
We can make the default constructor `const` since `MyOtherClass` has a const constructor:
```dart
class MyClass {
// ...
const MyClass(this.value, this.other);
}
const myConst = MyClass(1, MyOtherClass(1));
```
However, we cant do:
```dart
class MyClass {
// ...
const MyClass.sameOther(int value)
// why does this work ...
: this.value = value,
// ... but this does not
other = MyOtherClass(value);
// ----------^^^^^^^^^^^^^^^^^^^^^
// Invalid const value
}
```
_____
Since the `const` part of the constructor is only used in `const` context, I had the following mental model:
Used in `const` context.
```dart
class MyClass {
const int value;
const MyOtherClass other;
const MyClass(this.value, this.other);
const MyClass.sameOther(const int value)
: this.value = value,
other = const MyOtherClass(value);
}
```
Used outside of `const` context.
```dart
class MyClass {
final int value;
final MyOtherClass other;
MyClass(this.value, this.other);
MyClass.sameOther(int value)
: this.value = value,
other = MyOtherClass(value);
}
```
_____
P.S.
I recently assumed that fields of an object created via `const` would be `const` as well, which might be related (even if only in my wrong mental model)
(https://github.com/dart-lang/language/issues/1868#issuecomment-925587460)
Contributor guide
Assessment
This issue has not been assessed yet.