Field promotion doesn't support late fields on DDC and dart2wasm
The following code is allowed on dart2js and the VM, but fails on DDC and dart2wasm:
class C {
late final int? _finalWithInitializer = 0;
late final int? _finalWithoutInitializer;
C() {
_finalWithoutInitializer = 0;
}
void test() {
if (_finalWithInitializer != null) {
print(_finalWithInitializer + 1);
}
if (_finalWithoutInitializer != null) {
print(_finalWithoutInitializer + 1);
}
}
}
What's happening is that DDC and dart2wasm lower late final fields to a synthetic getter. The logic in the CFE for deciding whether a property access is promotable needs to understand that a synthetic getter that came from a late final field is still ok to promote.
I'm working on a fix.
An issue was opened in the flutter repo demonstrating this bug still exists in some cases.
I've confirmed locally that I can repro the same behavior. Here's my minimal repro:
typedef Callback = void Function();
class Foo {
late final Callback? _koCallback;
final Callback? _okCallback;
Foo({
Callback? okCallback,
Callback? koCallback,
}) : _okCallback = okCallback {
_koCallback = koCallback;
}
void thisWorks() {
_okCallback == null ? null : (value) => _okCallback();
}
void thisDoesNot() {
_koCallback == null ? null : (value) => _koCallback();
}
}
void main() {}
Running $DART_SDK/out/ReleaseX64/dart $DART_SDK/pkg/dev_compiler/tool/ddb --debug -r chrome <file>.dart locally gives me:
org-dartlang-app:/test.dart:19:56: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null.
Try calling using ?.call instead.
_koCallback == null ? null : (value) => _koCallback();
Running with the VM or dart2js compiles/executes as expected.
This is also reproducible in dartpad with the above example since it uses DDC.
The Flutter issue referred above is marked as a P2 so bumping the priority of this issue accordingly.
@stereotype441 Any plans for looking into this in the near future? The flutter issue is still open and the minimal reproduction in this thread is still valid.
CC @johnniwinther