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.:
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:
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:
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:
class MyClass {
// ...
const MyClass(this.value, this.other);
}
const myConst = MyClass(1, MyOtherClass(1));
However, we cant do:
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.
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.
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)
(#1868 (comment))