Skip to content

Commit f18ecfa

Browse files
authored
#2420. Add more exhaustiveness tests (#2513)
Add more exhaustiveness tests
1 parent 4fb873e commit f18ecfa

6 files changed

+134
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
/// @assertion Extension type erasure is not used during flow analysis
6+
///
7+
/// @description Check that an extension type erasure is not used during flow
8+
/// analysis that isn't concerned with run-time type tests
9+
/// @author [email protected]
10+
11+
// SharedOptions=--enable-experiment=inline-class
12+
13+
extension type const ET1(int value) {
14+
void confirmET1() {}
15+
}
16+
extension type const ET2(int value) implements int {
17+
void confirmET2() {}
18+
}
19+
20+
void main() {
21+
int i = 42;
22+
switch (i) {
23+
case ET1 v:
24+
v.confirmET1(); // This confirms that `ET1` is not erased to int
25+
}
26+
switch (i) {
27+
case ET2 v:
28+
v.confirmET2();
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
/// @assertion Exhaustiveness of a variable pattern is determined by the static
6+
/// type of the corresponding variable.
7+
///
8+
/// @description Check static type of a variable pattern
9+
/// @author [email protected]
10+
11+
// SharedOptions=--enable-experiment=inline-class
12+
13+
import '../../Utils/static_type_helper.dart';
14+
15+
extension type ET(int i) {}
16+
extension type TO(int i) implements ET {}
17+
18+
main() {
19+
ET x = ET(1);
20+
switch (x) {
21+
case int y:
22+
x.expectStaticType<Exactly<ET>>;
23+
y.expectStaticType<Exactly<int>>;
24+
case TO z: // Unreachable, it's Ok
25+
x.expectStaticType<Exactly<TO>>;
26+
z.expectStaticType<Exactly<TO>>;
27+
}
28+
switch (42) {
29+
case ET y:
30+
x.expectStaticType<Exactly<ET>>;
31+
y.expectStaticType<Exactly<ET>>;
32+
case TO z: // Unreachable, it's Ok
33+
x.expectStaticType<Exactly<ET>>;
34+
z.expectStaticType<Exactly<TO>>;
35+
}
36+
}

LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_lib.dart

+4
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,7 @@ class LastPersonOnEarth<T> implements Jack<T>, Queen<T>, King<T> {
4646

4747
LastPersonOnEarth(this.suit, {this.oneEyed = false});
4848
}
49+
50+
sealed class SClass {}
51+
class B1Class extends SClass {}
52+
class B2Class extends SClass {}

LanguageFeatures/Patterns/Exhaustiveness/exhaustiveness_sealed_A02_t02.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/// matched type are always exhaustive
77
///
88
/// @description Check that it is a compile-time error if the matched value type
9-
/// of a switch expression or stetement is a sealed class and the set of cases
9+
/// of a switch expression or statement is a sealed class and the set of cases
1010
/// is not exhaustive
1111
/// @author [email protected]
1212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
/// @assertion Switch statements and expressions with a sealed class as a
6+
/// matched type are always exhaustive
7+
///
8+
/// @description Check that the flow analysis considers a case reachable even in
9+
/// the case where it accepts only objects of an unrelated type.
10+
/// @author [email protected]
11+
12+
class A {}
13+
14+
class B {}
15+
16+
void main() {
17+
int x;
18+
A a = A();
19+
switch (a) {
20+
case B():
21+
print(
22+
'''x is not assigned here. This case looks impossible, but there can
23+
be a hidden subtype of A and B in some other library''');
24+
case _:
25+
x = 1;
26+
}
27+
print(x);
28+
// ^
29+
// [analyzer] unspecified
30+
// [cfe] unspecified
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
/// @assertion Switch statements and expressions with a sealed class as a
6+
/// matched type are always exhaustive
7+
///
8+
/// @description Check that the flow analysis considers a case reachable even in
9+
/// the case where it accepts only objects of an unrelated type.
10+
/// @author [email protected]
11+
12+
import 'exhaustiveness_lib.dart';
13+
14+
class C {}
15+
class D extends C implements B1Class {}
16+
17+
void main() {
18+
int x;
19+
SClass s = D();
20+
switch (s) {
21+
case C():
22+
print('x is not assigned here');
23+
case B1Class():
24+
x = 1;
25+
case B2Class():
26+
x = 2;
27+
}
28+
print(x);
29+
// ^
30+
// [analyzer] unspecified
31+
// [cfe] unspecified
32+
}

0 commit comments

Comments
 (0)