blob: 11a3d2b15a84b5222ebb20ab759b3b4e12611951 [file] [log] [blame]
// Copyright (c) 2020, 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 '../../static_type_helper.dart';
/// Test that promotion logic properly understands the type of a late variable.
/// In particular, make sure that CFE late lowering doesn't cause flow analysis
/// to treat the type as nullable when it's non-nullable.
void nonNullableInitializedWithType() {
late num x = 0;
x.expectStaticType<Exactly<num>>();
// Attempting to promote to `int?` should do nothing, since `int?` is not a
// subtype of `num`.
if (x is int?) {
x.expectStaticType<Exactly<num>>();
}
// Attempting to promote to `int` should be ok, though.
if (x is int) {
x.expectStaticType<Exactly<int>>();
}
}
void nullableInitializedWithType() {
late num? x = 0 as num?; // Cast to prevent promotion
x.expectStaticType<Exactly<num?>>();
// Attempting to promote to `num` should be ok, since `num` is a subtype of
// `num?`.
if (x is num) {
x.expectStaticType<Exactly<num>>();
}
// Attempting to promote to `int?` should be ok too.
if (x is int?) {
x.expectStaticType<Exactly<int?>>();
}
}
void nonNullableInitializedUntyped() {
late var x = 0 as num;
x.expectStaticType<Exactly<num>>();
// Attempting to promote to `int?` should do nothing, since `int?` is not a
// subtype of `num`.
if (x is int?) {
x.expectStaticType<Exactly<num>>();
}
// Attempting to promote to `int` should be ok, though.
if (x is int) {
x.expectStaticType<Exactly<int>>();
}
}
void nullableInitializedUntyped() {
late var x = 0 as num?;
x.expectStaticType<Exactly<num?>>();
// Attempting to promote to `num` should be ok, since `num` is a subtype of
// `num?`.
if (x is num) {
x.expectStaticType<Exactly<num>>();
}
// Attempting to promote to `int?` should be ok too.
if (x is int?) {
x.expectStaticType<Exactly<int?>>();
}
}
void nonNullableUninitializedWithType() {
late num x;
x = 0;
x.expectStaticType<Exactly<num>>();
// Attempting to promote to `int?` should do nothing, since `int?` is not a
// subtype of `num`.
if (x is int?) {
x.expectStaticType<Exactly<num>>();
}
// Attempting to promote to `int` should be ok, though.
if (x is int) {
x.expectStaticType<Exactly<int>>();
}
}
void nullableUninitializedWithType() {
late num? x;
x = 0 as num?; // Cast to prevent promotion
x.expectStaticType<Exactly<num?>>();
// Attempting to promote to `num` should be ok, since `num` is a subtype of
// `num?`.
if (x is num) {
x.expectStaticType<Exactly<num>>();
}
// Attempting to promote to `int?` should be ok too.
if (x is int?) {
x.expectStaticType<Exactly<int?>>();
}
}
void uninitializedUntyped() {
late var x;
x = 0;
if (false) {
// Check that the static type of [x] is dynamic:
Never n = x;
x = 0;
x = false;
}
// Attempting to promote to `int?` should be ok, since `int?` is a subtype of
// `dynamic`.
if (x is int?) {
x.expectStaticType<Exactly<int?>>();
}
// Attempting to promote to `int` should be ok too.
if (x is int) {
x.expectStaticType<Exactly<int>>();
}
}
main() {
nonNullableInitializedWithType();
nullableInitializedWithType();
nonNullableInitializedUntyped();
nullableInitializedUntyped();
nonNullableUninitializedWithType();
nullableUninitializedWithType();
uninitializedUntyped();
}