blob: a6291a51561e907283f19c8c83fcb1f0e3979d03 [file] [log] [blame]
// Copyright (c) 2023, 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() {
{
// A null-check pattern may fail to match.
int? reachability0 = 0;
if (expr<Object?>() case _?) {
} else {
reachability0 = null;
}
reachability0.expectStaticType<Exactly<int?>>();
}
{
// A scrutinee that has been modified inside a `when` clause is not
// promoted.
var x = expr<Object?>();
switch (x) {
case _ when pickSecond(x = expr<Object?>(), expr<bool>()):
break;
case _?:
x.expectStaticType<Exactly<Object?>>();
}
}
{
// A scrutinee that hasn't been modified is promoted.
var x = expr<Object?>();
if (x case _?) {
x.expectStaticType<Exactly<Object>>();
} else {
x.expectStaticType<Exactly<Object?>>();
}
}
{
// If the null-check is applied to a subpattern, the scrutinee is not
// promoted.
var x = expr<Object?>();
if (x case NullableInt(foo: _?)) {
x.expectStaticType<Exactly<int?>>();
}
}
{
// The matched value is promoted.
if (expr<Object?>() case _? && var x) {
x.expectStaticType<Exactly<Object>>();
}
}
{
// If the matched value type is `Null`, then a null-check pattern is
// guaranteed not to match.
int? reachability0 = 0;
if (expr<Null>() case _?) {
reachability0 = null;
}
reachability0.expectStaticType<Exactly<int>>();
}
{
// Otherwise, it may match.
int? reachability0 = 0;
if (expr<Object?>() case _?) {
reachability0 = null;
}
reachability0.expectStaticType<Exactly<int?>>();
}
{
// If the scrutinee is already promoted, a subsequent null-check pattern
// doesn't demote it.
var x = expr<Object?>();
if (x case (_ as int? && _?) && var y) {
x.expectStaticType<Exactly<int>>();
y.expectStaticType<Exactly<int>>();
}
}
{
// Inside a record pattern, a null-check pattern can promote the record's
// field type.
var x = expr<(int?,)>();
if (x case (_?,)) {
x.expectStaticType<Exactly<(int,)>>();
}
}
}
T expr<T>() => throw UnimplementedError();
T pickSecond<T>(dynamic x, T y) => y;
extension on int? {
dynamic get foo => throw UnimplementedError();
}
typedef NullableInt = int?;
main() {}