Skip to content

Commit 764003b

Browse files
committed
dart-lang#2420. Exhaustiveness variable tests. Add switch statement check
1 parent 89ec72c commit 764003b

14 files changed

+485
-34
lines changed

LanguageFeatures/Extension-types/exhaustiveness_variable_A01_t01.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ extension type AET2(A _) implements A {}
2626
extension type BET1(B _) {}
2727
extension type BET2(B _) implements B {}
2828

29-
test1(AET1 a) => switch (a) { B _ => 'B' };
30-
test2(AET2 a) => switch (a) { B _ => 'B' };
29+
String test1(AET1 a) => switch (a) { B _ => 'B' };
30+
String test2(AET2 a) => switch (a) { B _ => 'B' };
3131

3232
main() {
3333
Expect.equals("B", test1(AET1(B())));

LanguageFeatures/Extension-types/exhaustiveness_variable_A01_t02.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ extension type BET2(B _) implements B {}
2525
extension type CET1(C _) {}
2626
extension type CET2(C _) implements A {} // Let's check implements A, not C
2727

28-
test1_1(A a) => switch (a) { CET1 _ => 'C', BET1 _ => 'B' };
29-
test1_2(A a) => switch (a) { BET2 _ => 'B', CET2 _ => 'C' };
28+
String test1_1(A a) => switch (a) { CET1 _ => 'C', BET1 _ => 'B' };
29+
String test1_2(A a) => switch (a) { BET2 _ => 'B', CET2 _ => 'C' };
3030

31-
test2_1(A a) => switch (a) { BET1 _ => 'B', CET1 _ => 'C' };
32-
test2_2(A a) => switch (a) { CET2 _ => 'C', BET2 _ => 'B' };
31+
String test2_1(A a) => switch (a) { BET1 _ => 'B', CET1 _ => 'C' };
32+
String test2_2(A a) => switch (a) { CET2 _ => 'C', BET2 _ => 'B' };
3333

3434
main() {
3535
Expect.equals("B", test1_1(B()));

LanguageFeatures/Extension-types/exhaustiveness_variable_A01_t03.dart

+6-6
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ extension type BET2(B _) implements B {}
2828
extension type CET1(C _) {}
2929
extension type CET2(C _) implements C {}
3030

31-
test1_1(AET1 a) => switch (a) { BET1 _ => 'B', CET1 _ => 'C' };
32-
test1_2(AET2 a) => switch (a) { BET2 _ => 'B', CET2 _ => 'C' };
31+
String test1_1(AET1 a) => switch (a) { BET1 _ => 'B', CET1 _ => 'C' };
32+
String test1_2(AET2 a) => switch (a) { BET2 _ => 'B', CET2 _ => 'C' };
3333

34-
test2_1(AET1 a) => switch (a) { BET1 _ => 'B', CET1 _ => 'C' };
35-
test2_2(AET2 a) => switch (a) { CET2 _ => 'C', BET2 _ => 'B' };
34+
String test2_1(AET1 a) => switch (a) { BET1 _ => 'B', CET1 _ => 'C' };
35+
String test2_2(AET2 a) => switch (a) { CET2 _ => 'C', BET2 _ => 'B' };
3636

37-
test3_1(AET1 a) => switch (a) { BET1 _ => 'B', C _ => 'C' };
38-
test3_2(AET2 a) => switch (a) { CET2 _ => 'C', B _ => 'B' };
37+
String test3_1(AET1 a) => switch (a) { BET1 _ => 'B', C _ => 'C' };
38+
String test3_2(AET2 a) => switch (a) { CET2 _ => 'C', B _ => 'B' };
3939

4040
main() {
4141
Expect.equals("B", test1_1(AET1(B())));

LanguageFeatures/Extension-types/exhaustiveness_variable_A01_t04.dart

+2-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@ class B extends A {}
2121

2222
class C extends B {}
2323

24-
extension type AET1(A _) {}
25-
extension type AET2(A _) implements A {}
2624
extension type BET1(B _) {}
2725
extension type BET2(B _) implements B {}
2826

29-
test1(BET1 b) => switch (b) { B _ => 'B' };
30-
test2(BET2 b) => switch (b) { B _ => 'B' };
27+
String test1(BET1 b) => switch (b) { B _ => 'B' };
28+
String test2(BET2 b) => switch (b) { B _ => 'B' };
3129

3230
main() {
3331
Expect.equals("B", test1(BET1(B())));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) 2023, 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 Switch statements and expressions with a sealed class as a
6+
/// matched type are always exhaustive if the set of cases is exhaustive
7+
///
8+
/// @description Check that it is no compile-time error if the matched value
9+
/// type of a switch statement is an extension type with a sealed class as a
10+
/// representation type and the set of cases is an exhaustive set of variable
11+
/// patterns
12+
/// @author [email protected]
13+
14+
// SharedOptions=--enable-experiment=inline-class
15+
16+
import "../../Utils/expect.dart";
17+
18+
sealed class A {}
19+
20+
class B extends A {}
21+
22+
class C extends B {}
23+
24+
extension type AET1(A _) {}
25+
extension type AET2(A _) implements A {}
26+
extension type BET1(B _) {}
27+
extension type BET2(B _) implements B {}
28+
29+
String test1(AET1 a) {
30+
switch (a) {
31+
case B _: return 'B';
32+
}
33+
}
34+
35+
String test2(AET2 a) {
36+
switch (a) {
37+
case B _: return 'B';
38+
}
39+
}
40+
41+
main() {
42+
Expect.equals("B", test1(AET1(B())));
43+
Expect.equals("B", test1(AET1(C())));
44+
Expect.equals("B", test2(AET2(B())));
45+
Expect.equals("B", test2(AET2(C())));
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) 2023, 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 Switch statements and expressions with a sealed class as a
6+
/// matched type are always exhaustive if the set of cases is exhaustive
7+
///
8+
/// @description Check that it is no compile-time error if the matched value
9+
/// type of a switch statement is a sealed class and the set of cases is an
10+
/// exhaustive set of variable patterns with extension types
11+
/// @author [email protected]
12+
13+
// SharedOptions=--enable-experiment=inline-class
14+
15+
import "../../Utils/expect.dart";
16+
17+
sealed class A {}
18+
19+
class B extends A {}
20+
21+
class C extends A {}
22+
23+
extension type BET1(B _) {}
24+
extension type BET2(B _) implements B {}
25+
extension type CET1(C _) {}
26+
extension type CET2(C _) implements A {} // Let's check implements A, not C
27+
28+
String test1_1(A a) {
29+
switch (a) {
30+
case CET1 _: return 'C';
31+
case BET1 _: return 'B';
32+
}
33+
}
34+
35+
String test1_2(A a) {
36+
switch (a) {
37+
case BET2 _: return 'B';
38+
case CET2 _: return 'C';
39+
}
40+
}
41+
42+
String test2_1(A a) {
43+
switch (a) {
44+
case BET1 _: return 'B';
45+
case CET1 _: return 'C';
46+
}
47+
}
48+
49+
String test2_2(A a) {
50+
switch (a) {
51+
case CET2 _: return 'C';
52+
case BET2 _: return 'B';
53+
}
54+
}
55+
56+
main() {
57+
Expect.equals("B", test1_1(B()));
58+
Expect.equals("C", test1_1(C()));
59+
Expect.equals("B", test1_2(B()));
60+
Expect.equals("C", test1_2(C()));
61+
62+
Expect.equals("B", test2_1(B()));
63+
Expect.equals("C", test2_1(C()));
64+
Expect.equals("B", test2_2(B()));
65+
Expect.equals("C", test2_2(C()));
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright (c) 2023, 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 Switch statements and expressions with a sealed class as a
6+
/// matched type are always exhaustive if the set of cases is exhaustive
7+
///
8+
/// @description Check that it is no compile-time error if the matched value
9+
/// type of a switch statement is an extension type with a sealed class as a
10+
/// representation type and the set of cases is an exhaustive set of variable
11+
/// patterns with extension types and classes
12+
/// @author [email protected]
13+
14+
// SharedOptions=--enable-experiment=inline-class
15+
16+
import "../../Utils/expect.dart";
17+
18+
sealed class A {}
19+
20+
class B extends A {}
21+
22+
class C extends A {}
23+
24+
extension type AET1(A _) {}
25+
extension type AET2(A _) implements A {}
26+
extension type BET1(B _) {}
27+
extension type BET2(B _) implements B {}
28+
extension type CET1(C _) {}
29+
extension type CET2(C _) implements C {}
30+
31+
String test1_1(AET1 a) {
32+
switch (a) {
33+
case BET1 _: return 'B';
34+
case CET1 _: return 'C';
35+
}
36+
}
37+
38+
String test1_2(AET2 a) {
39+
switch (a) {
40+
case BET2 _: return 'B';
41+
case CET2 _: return 'C';
42+
}
43+
}
44+
45+
String test2_1(AET1 a) {
46+
switch (a) {
47+
case BET1 _: return 'B';
48+
case CET1 _: return 'C';
49+
}
50+
}
51+
52+
String test2_2(AET2 a) {
53+
switch (a) {
54+
case CET2 _: return 'C';
55+
case BET2 _: return 'B';
56+
}
57+
}
58+
59+
String test3_1(AET1 a) {
60+
switch (a) {
61+
case BET1 _: return 'B';
62+
case C _: return 'C';
63+
}
64+
}
65+
66+
String test3_2(AET2 a) {
67+
switch (a) {
68+
case CET2 _: return 'C';
69+
case B _: return 'B';
70+
}
71+
}
72+
73+
main() {
74+
Expect.equals("B", test1_1(AET1(B())));
75+
Expect.equals("C", test1_1(AET1(C())));
76+
Expect.equals("B", test1_2(AET2(B())));
77+
Expect.equals("C", test1_2(AET2(C())));
78+
79+
Expect.equals("B", test2_1(AET1(B())));
80+
Expect.equals("C", test2_1(AET1(C())));
81+
Expect.equals("B", test2_2(AET2(B())));
82+
Expect.equals("C", test2_2(AET2(C())));
83+
84+
Expect.equals("B", test3_1(AET1(B())));
85+
Expect.equals("C", test3_1(AET1(C())));
86+
Expect.equals("B", test3_2(AET2(B())));
87+
Expect.equals("C", test3_2(AET2(C())));
88+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) 2023, 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 Switch statements and expressions with a some class as a matched
6+
/// type are always exhaustive if the set of cases is exhaustive
7+
///
8+
/// @description Check that it is no compile-time error if the matched value
9+
/// type of a switch statement is an extension type with some class as a
10+
/// representation type and the set of cases is an exhaustive set of variable
11+
/// patterns
12+
/// @author [email protected]
13+
/// @issue 54444
14+
15+
// SharedOptions=--enable-experiment=inline-class
16+
17+
import "../../Utils/expect.dart";
18+
19+
class A {}
20+
21+
class B extends A {}
22+
23+
class C extends B {}
24+
25+
extension type BET1(B _) {}
26+
extension type BET2(B _) implements B {}
27+
28+
String test1(BET1 b) {
29+
switch (b) {
30+
case B _: return 'B';
31+
}
32+
}
33+
34+
String test2(BET2 b) {
35+
switch (b) {
36+
case B _: return 'B';
37+
}
38+
}
39+
40+
main() {
41+
Expect.equals("B", test1(BET1(B())));
42+
Expect.equals("B", test1(BET1(C())));
43+
Expect.equals("B", test2(BET2(B())));
44+
Expect.equals("B", test2(BET2(C())));
45+
}

LanguageFeatures/Extension-types/exhaustiveness_variable_A02_t01.dart

+4-6
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,12 @@ class C extends A<int> {}
2121

2222
extension type AET1<T>(A<T> _) {}
2323
extension type AET2<T>(A<T> _) implements A<T> {}
24-
extension type BET1<T>(B<T> _) {}
25-
extension type BET2<T>(B<T> _) implements B<T> {}
2624

27-
test1_1(AET1<String> a) => switch (a) { B _ => 'B'};
28-
test1_2(AET2<String> a) => switch (a) { B _ => 'B'};
25+
String test1_1(AET1<String> a) => switch (a) { B _ => 'B'};
26+
String test1_2(AET2<String> a) => switch (a) { B _ => 'B'};
2927

30-
test2_1(AET1<int> a) => switch (a) { B _ => 'B', C _ => 'C'};
31-
test2_2(AET2<int> a) => switch (a) { B _ => 'B', C _ => 'C'};
28+
String test2_1(AET1<int> a) => switch (a) { B _ => 'B', C _ => 'C'};
29+
String test2_2(AET2<int> a) => switch (a) { B _ => 'B', C _ => 'C'};
3230

3331
main() {
3432
Expect.equals("B", test1_1(AET1(B<String>())));

LanguageFeatures/Extension-types/exhaustiveness_variable_A02_t02.dart

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ extension type BET2<T>(B<T> _) implements B<T> {}
2525
extension type CET1(C _) {}
2626
extension type CET2(C _) implements C {}
2727

28-
test1_1(A<String> a) => switch (a) { BET1 _ => 'B'};
29-
test1_2(A<String> a) => switch (a) { BET2 _ => 'B'};
28+
String test1_1(A<String> a) => switch (a) { BET1 _ => 'B'};
29+
String test1_2(A<String> a) => switch (a) { BET2 _ => 'B'};
3030

31-
test2_1(A<int> a) => switch (a) { BET1 _ => 'B', CET1 _ => 'C'};
32-
test2_2(A<int> a) => switch (a) { BET2 _ => 'B', CET2 _ => 'C'};
31+
String test2_1(A<int> a) => switch (a) { BET1 _ => 'B', CET1 _ => 'C'};
32+
String test2_2(A<int> a) => switch (a) { BET2 _ => 'B', CET2 _ => 'C'};
3333

34-
test3_1(A<int> a) => switch (a) { AET1 _ => 'A'};
35-
test3_2(A<int> a) => switch (a) { AET2 _ => 'A'};
34+
String test3_1(A<int> a) => switch (a) { AET1 _ => 'A'};
35+
String test3_2(A<int> a) => switch (a) { AET2 _ => 'A'};
3636

3737
main() {
3838
Expect.equals("B", test1_1(B<String>()));

LanguageFeatures/Extension-types/exhaustiveness_variable_A02_t03.dart

+6-6
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ extension type BET2<T>(B<T> _) implements B<T> {}
2626
extension type CET1(C _) {}
2727
extension type CET2(C _) implements C {}
2828

29-
test1_1(AET1<String> a) => switch (a) { BET1 _ => 'B'};
30-
test1_2(AET2<String> a) => switch (a) { BET2 _ => 'B'};
29+
String test1_1(AET1<String> a) => switch (a) { BET1 _ => 'B'};
30+
String test1_2(AET2<String> a) => switch (a) { BET2 _ => 'B'};
3131

32-
test2_1(AET1<int> a) => switch (a) { BET1 _ => 'B', C _ => 'C'};
33-
test2_2(AET2<int> a) => switch (a) { B _ => 'B', CET2 _ => 'C'};
32+
String test2_1(AET1<int> a) => switch (a) { BET1 _ => 'B', C _ => 'C'};
33+
String test2_2(AET2<int> a) => switch (a) { B _ => 'B', CET2 _ => 'C'};
3434

35-
test3_1(AET1<int> a) => switch (a) { AET1 _ => 'A'};
36-
test3_2(AET2<int> a) => switch (a) { AET2 _ => 'A'};
35+
String test3_1(AET1<int> a) => switch (a) { AET1 _ => 'A'};
36+
String test3_2(AET2<int> a) => switch (a) { AET2 _ => 'A'};
3737

3838
main() {
3939
Expect.equals("B", test1_1(AET1(B<String>())));

0 commit comments

Comments
 (0)