blob: fe5114d777c48ce1c6444d18ec8b986a30a9db01 [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-assert pattern cannot 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-assert 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-assert pattern is
// guaranteed not to match.
int? reachability0 = 0;
if (expr<bool>()) {
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-assert 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-assert 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() {}