Description
This issue describes a small, potential relaxation of a compile-time error. It may seem like a small bug fix, but we wish to ensure that the implementation effort isn't large, either, and check that the change does not have unexpected implications.
The relaxation is that a class can have a constant factory constructor and a late final instance variable, which used to be a compile-time error.
Cf. issue dart-lang/language#1763 and PR dart-lang/language#1764, and the following program:
class Base {
Base();
const factory Base.empty() = _Empty;
late final int property;
}
class _Empty implements Base {
const _Empty();
int get property => 2;
set property(_) => throw "Property cannot be initialized";
}
void main() {}
Class Base
is an error according to the specification, and it is reported as a compile-time error by the analyzer (from 4fc912c):
ERROR|COMPILE_TIME_ERROR|LATE_FINAL_FIELD_WITH_CONST_CONSTRUCTOR|/usr/local/google/home/eernst/lang/dart/scratch/202107/n048.dart|4|3|4|Can't have a late final field in a class with a const constructor.
However, the program is accepted by the CFE (and dart
runs the program, with no dynamic errors).
The error arises because Base
contains a late final
instance variable and a constant constructor.
The motivation for this error would be that a constant expression cannot yield an object with mutable state, and a late final instance variable in general allows for mutation after creation. However, the error is not necessary when the constant constructor is a factory constructor, as in the example above.
It might seem unnecessary to make a late final instance variable with an initializer an error when there is a generative constant constructor, because this kind of variable will only ever have one single value (and there is no setter). However, that value should be obtained when the variable is first evaluated; that evaluation could run arbitrary code, and hence it's incompatible with constant expression evaluation.
So I'd recommend that we change the spec as it is done in dart-lang/language#1764, thus relaxing this error a bit and allowing the factory constructor.