Skip to content

Commit cc726b8

Browse files
authored
#3057. Add more flow analysis tests, fix existing (#3117)
Add more flow analysis tests, fix existing
1 parent 2011443 commit cc726b8

7 files changed

+137
-12
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2025, 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+
/// @assertion type cast If `N` is an expression of the form `E1 as S` where the
6+
/// static type of `E1` is `T` then:
7+
/// - Let `before(E1) = before(N)`
8+
/// - Let `after(N) = promote(E1, S, after(E1))`
9+
///
10+
/// @description Checks that `after(N) = promote(E1, S, after(E1))`.
11+
/// @author [email protected]
12+
13+
import '../../Utils/static_type_helper.dart';
14+
15+
main() {
16+
int? i = 2 > 1 ? 42 : null;
17+
i as int;
18+
i.expectStaticType<Exactly<int>>();
19+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (c) 2025, 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+
/// @assertion type cast If `N` is an expression of the form `E1 as S` where the
6+
/// static type of `E1` is `T` then:
7+
/// - Let `before(E1) = before(N)`
8+
/// - Let `after(N) = promote(E1, S, after(E1))`
9+
///
10+
/// @description Checks that `after(N) = promote(E1, S, after(E1))`. Test that
11+
/// after promotion to `Never` `after(N)` became unreachable.
12+
/// @author [email protected]
13+
14+
test1(x) {
15+
late int i;
16+
if (1 > 2) {
17+
x as Never;
18+
i = 42;
19+
}
20+
i; // Definitely unassigned
21+
//^
22+
// [analyzer] unspecified
23+
// [cfe] unspecified
24+
}
25+
26+
test2(x) {
27+
late int i;
28+
if (1 > 2) {
29+
i = 42;
30+
x as Never;
31+
}
32+
i; // Definitely unassigned
33+
//^
34+
// [analyzer] unspecified
35+
// [cfe] unspecified
36+
}
37+
38+
main() {
39+
test1(42);
40+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) 2025, 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+
/// @assertion Conditional statement: If `N` is a conditional statement of the
6+
/// form `if (E) S1 else S2` then:
7+
/// - Let `before(E) = before(N)`.
8+
/// - Let `before(S1) = split(true(E))`.
9+
/// - Let `before(S2) = split(false(E))`.
10+
/// - Let `after(N) = merge(after(S1), after(S2))`.
11+
///
12+
/// @description Checks that if `after(S1)` or `after(S2)` is unreachable then
13+
/// an assignment in the appropriate branch is omitted by the `join`.
14+
/// @author [email protected]
15+
16+
Never foo() => throw "Never";
17+
18+
void test1() {
19+
late int i;
20+
if (2 > 1) {
21+
i = 0;
22+
foo();
23+
}
24+
i; // Definitely unassigned
25+
//^
26+
// [analyzer] unspecified
27+
// [cfe] unspecified
28+
}
29+
30+
void test2(Never n) {
31+
late int i;
32+
if (2 > 1) {
33+
} else {
34+
i = 0;
35+
n;
36+
}
37+
i; // Definitely unassigned
38+
//^
39+
// [analyzer] unspecified
40+
// [cfe] unspecified
41+
}
42+
43+
main() {
44+
print(test1);
45+
print(test2);
46+
}

TypeSystem/flow-analysis/reachability_for_in_A01_t04.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,7 @@ test4() {
5353
if (2 > 1) {
5454
for (i in <Never>[]) {}
5555
}
56-
i; // Definitely unassigned.
57-
//^
58-
// [analyzer] unspecified
59-
// [cfe] unspecified
56+
i; // Not definitely unassigned.
6057
}
6158

6259
main() {

TypeSystem/flow-analysis/reachability_for_in_A01_t05.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,7 @@ test4() {
6161
i = 42;
6262
}
6363
}
64-
i; // Definitely unassigned.
65-
//^
66-
// [analyzer] unspecified
67-
// [cfe] unspecified
64+
i; // Not definitely unassigned.
6865
}
6966

7067
main() {

TypeSystem/flow-analysis/reachability_for_in_A01_t06.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@ test4() {
5757
for (var j in <Never>[]) {}
5858
i = 42;
5959
}
60-
i; // Definitely unassigned.
61-
//^
62-
// [analyzer] unspecified
63-
// [cfe] unspecified
60+
i; // Not definitely unassigned.
6461
}
6562

6663
main() {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2025, 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+
/// @assertion for each statement: If `N` is a for statement of the form
6+
/// `for (T X in E) S`, `for (var X in E) S`, or `for (X in E) S`, then:
7+
/// - Let `before(E) = before(N)`
8+
/// - Let `before(S) = conservativeJoin(after(E), assignedIn(N), capturedIn(N))`
9+
/// - Let `after(N) = join(before(S), break(S))`
10+
///
11+
/// @description Checks that
12+
/// `before(S) = conservativeJoin(after(E), assignedIn(N), capturedIn(N))`. Test
13+
/// that if a promoted variable is assigned in `X` then it preserves the
14+
/// promoted type.
15+
/// @author [email protected]
16+
17+
test(int? n) {
18+
if (n != null) { // n promoted to `int`
19+
for (n in [42]) { // n is not promoted not demoted here
20+
n.isEven; // n is still `int`
21+
}
22+
n.isEven;
23+
}
24+
}
25+
26+
main() {
27+
test(42);
28+
test(null);
29+
}

0 commit comments

Comments
 (0)