dart-sdk/tests/web/late_narrowing_test.dart
Mayank Patke f5b8cc2c76 [dart2js] Improve type inference for createSentinel.
Treating createSentinel as returning a value of type Never caused issues
whenever its result flowed into a union, since the union would just
simplify to its other component. This meant that if a late field started
out uninitialized and was later initialized to a constant, we would see
it as only ever having the constant value. This caused isSentinel to
always return false even if the field hadn't been initialized yet.

Instead, we support a late sentinel value in the abstract value domain
and use this value as the return type of createSentinel during
inference. Additionally, inference treats _lateReadCheck as a simple
narrowing to exclude the late sentinel value.

Change-Id: I086bfd77576930e3ca2a4cfc9bd63476b6636685
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210646
Reviewed-by: Stephen Adams <sra@google.com>
2021-09-13 21:59:20 +00:00

24 lines
787 B
Dart

// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:expect/expect.dart';
// Tests to ensure that narrowing type information does not discard late
// sentinel values unintentionally.
class Foo<T> {
// Since `List<T>` contains a free type variable, any access of [x] will be
// immediately followed by a narrowing to the appropriate instantiation of
// `List<T>`. This narrowing should not exclude the late sentinel value from
// the abstract value.
late final List<T> x;
}
void main() {
Foo<int> foo = Foo();
Expect.throws(() => foo.x);
foo.x = const [];
Expect.isTrue(foo.x.isEmpty);
}