Skip to content

Small relaxation of const constructor error #46758

Closed
@eernstg

Description

@eernstg

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-metaCross-cutting, high-level issues (for tracking many other implementation issues, ...).type-questionA question about expected behavior or functionality

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions