Skip to content

Commit 3d56a42

Browse files
kallentuCommit Queue
authored and
Commit Queue
committed
[flow][tests] Add language tests for promotion with assignment in if statements.
This CL adds language tests for this issue and makes sure the feature isn't enabled if `inference-update-4` feature flag isn't enabled. Companion CL for https://dart-review.googlesource.com/c/sdk/+/388903 which adds the behaviour for promoting in assignment expressions of if-statements. Bug: dart-lang/language#3658 Change-Id: I6c8d7f922b4c50d4655202e61cebaf8891daee0f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/389223 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Kallen Tu <[email protected]>
1 parent ddb81c1 commit 3d56a42

File tree

2 files changed

+218
-0
lines changed

2 files changed

+218
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Tests that assignment expressions in if statements as described
6+
// by https://github.com/dart-lang/language/issues/3658 don't promote when the
7+
// `inference-update-4` feature flag is disabled.
8+
9+
// @dart=3.6
10+
11+
import '../static_type_helper.dart';
12+
13+
class A {
14+
A operator +(int i) {
15+
return new B();
16+
}
17+
}
18+
19+
class B extends A {}
20+
21+
int? nullableInt() => 1;
22+
23+
testEqNull_assignIfNull() {
24+
int? x = null;
25+
if ((x ??= nullableInt()) == null) {
26+
x.expectStaticType<Exactly<int?>>();
27+
} else {
28+
// Since `inference-update-4` isn't enabled, flow analysis won't promote `x`
29+
// if it's in an assignment expression, leaving the type as `int?` even
30+
// though it can't be nullable in this `else`.
31+
x.expectStaticType<Exactly<int?>>();
32+
}
33+
x.expectStaticType<Exactly<int?>>();
34+
}
35+
36+
testEqNull_eq() {
37+
int? x = null;
38+
if ((x = nullableInt()) == null) {
39+
x.expectStaticType<Exactly<int?>>();
40+
} else {
41+
// Since `inference-update-4` isn't enabled, flow analysis won't promote `x`
42+
// if it's in an assignment expression, leaving the type as `int?` even
43+
// though it can't be nullable in this `else`.
44+
x.expectStaticType<Exactly<int?>>();
45+
}
46+
x.expectStaticType<Exactly<int?>>();
47+
}
48+
49+
testNeqNull_assignIfNull() {
50+
int? x = null;
51+
if ((x ??= nullableInt()) != null) {
52+
// Since `inference-update-4` isn't enabled, flow analysis won't promote `x`
53+
// if it's in an assignment expression, leaving the type as `int?`.
54+
x.expectStaticType<Exactly<int?>>();
55+
}
56+
x.expectStaticType<Exactly<int?>>();
57+
}
58+
59+
testNeqNull_eq() {
60+
int? x = null;
61+
if ((x = nullableInt()) != null) {
62+
// Since `inference-update-4` isn't enabled, flow analysis won't promote `x`
63+
// if it's in an assignment expression, leaving the type as `int?`.
64+
x.expectStaticType<Exactly<int?>>();
65+
}
66+
x.expectStaticType<Exactly<int?>>();
67+
}
68+
69+
testIs_eq() {
70+
int? x = null;
71+
if ((x = nullableInt()) is int) {
72+
// Since `inference-update-4` isn't enabled, flow analysis won't promote `x`
73+
// if it's in an assignment expression, leaving the type as `int?`.
74+
x.expectStaticType<Exactly<int?>>();
75+
}
76+
x.expectStaticType<Exactly<int?>>();
77+
}
78+
79+
testIs_plusEq() {
80+
A x = A();
81+
if ((x += 1) is B) {
82+
// Since `inference-update-4` isn't enabled, flow analysis won't promote `x`
83+
// if it's in an assignment expression, leaving the type as `A`.
84+
x.expectStaticType<Exactly<A>>();
85+
}
86+
x.expectStaticType<Exactly<A>>();
87+
}
88+
89+
testIs_postfix() {
90+
A x = A();
91+
if (x++ is B) {
92+
x.expectStaticType<Exactly<A>>();
93+
}
94+
x.expectStaticType<Exactly<A>>();
95+
}
96+
97+
testIs_prefix() {
98+
A x = A();
99+
if ((++x) is B) {
100+
// Since `inference-update-4` isn't enabled, flow analysis won't promote `x`
101+
// if it's in an assignment expression, leaving the type as `A`.
102+
x.expectStaticType<Exactly<A>>();
103+
}
104+
x.expectStaticType<Exactly<A>>();
105+
}
106+
107+
main() {
108+
testEqNull_assignIfNull();
109+
testEqNull_eq();
110+
testNeqNull_assignIfNull();
111+
testNeqNull_eq();
112+
testIs_eq();
113+
testIs_plusEq();
114+
testIs_postfix();
115+
testIs_prefix();
116+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Tests the promotion of assignment expressions in if statements as described
6+
// by https://github.com/dart-lang/language/issues/3658
7+
8+
// SharedOptions=--enable-experiment=inference-update-4
9+
10+
import '../static_type_helper.dart';
11+
12+
class A {
13+
A operator +(int i) {
14+
return new B();
15+
}
16+
}
17+
18+
class B extends A {}
19+
20+
int? nullableInt() => 1;
21+
22+
testEqNull_assignIfNull() {
23+
int? x = null;
24+
if ((x ??= nullableInt()) == null) {
25+
x.expectStaticType<Exactly<int?>>();
26+
} else {
27+
x.expectStaticType<Exactly<int>>();
28+
}
29+
x.expectStaticType<Exactly<int?>>();
30+
}
31+
32+
testEqNull_eq() {
33+
int? x = null;
34+
if ((x = nullableInt()) == null) {
35+
x.expectStaticType<Exactly<int?>>();
36+
} else {
37+
x.expectStaticType<Exactly<int>>();
38+
}
39+
x.expectStaticType<Exactly<int?>>();
40+
}
41+
42+
testNeqNull_assignIfNull() {
43+
int? x = null;
44+
if ((x ??= nullableInt()) != null) {
45+
x.expectStaticType<Exactly<int>>();
46+
}
47+
x.expectStaticType<Exactly<int?>>();
48+
}
49+
50+
testNeqNull_eq() {
51+
int? x = null;
52+
if ((x = nullableInt()) != null) {
53+
x.expectStaticType<Exactly<int>>();
54+
}
55+
x.expectStaticType<Exactly<int?>>();
56+
}
57+
58+
testIs_eq() {
59+
int? x = null;
60+
if ((x = nullableInt()) is int) {
61+
x.expectStaticType<Exactly<int>>();
62+
}
63+
x.expectStaticType<Exactly<int?>>();
64+
}
65+
66+
testIs_plusEq() {
67+
A x = A();
68+
if ((x += 1) is B) {
69+
x.expectStaticType<Exactly<B>>();
70+
}
71+
x.expectStaticType<Exactly<A>>();
72+
}
73+
74+
testIs_postfix() {
75+
A x = A();
76+
if ((x++) is B) {
77+
// No promotion because the value being is checked is the value of `x`
78+
// before the increment, and that value isn't relevant after the increment
79+
// occurs.
80+
x.expectStaticType<Exactly<A>>();
81+
}
82+
x.expectStaticType<Exactly<A>>();
83+
}
84+
85+
testIs_prefix() {
86+
A x = A();
87+
if ((++x) is B) {
88+
x.expectStaticType<Exactly<B>>();
89+
}
90+
x.expectStaticType<Exactly<A>>();
91+
}
92+
93+
main() {
94+
testEqNull_assignIfNull();
95+
testEqNull_eq();
96+
testNeqNull_assignIfNull();
97+
testNeqNull_eq();
98+
testIs_eq();
99+
testIs_plusEq();
100+
testIs_postfix();
101+
testIs_prefix();
102+
}

0 commit comments

Comments
 (0)