Skip to content

Commit 066b7e8

Browse files
committed
dart-lang#1401. Exhaustiveness tests added
1 parent 10710b0 commit 066b7e8

13 files changed

+548
-0
lines changed
Lines changed: 45 additions & 0 deletions
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 But switch statements must only be exhaustive when the matched
6+
/// value is an always-exhaustive type, defined as:
7+
/// - bool
8+
/// - Null
9+
/// - A enum type
10+
/// - A type whose declaration is marked sealed
11+
/// - T? where T is always-exhaustive
12+
/// - FutureOr<T> for some type T that is always-exhaustive
13+
/// - A record type whose fields all have always-exhaustive types
14+
/// - A type variable X with bound T where T is always-exhaustive
15+
/// - A promoted type variable X & T where T is always-exhaustive
16+
///
17+
/// All other types are not always-exhaustive. Then:
18+
/// - It is a compile-time error if the cases in a switch statement or switch
19+
/// collection element are not exhaustive and the static type of the matched
20+
/// value is an always-exhaustive type. There is no error if a switch
21+
/// statement is not exhaustive when the type is not an always-exhaustive type
22+
///
23+
/// @description Check that it is a compile-time error if a switch statement is
24+
/// not exhaustive. Test `bool`
25+
/// @author [email protected]
26+
27+
// SharedOptions=--enable-experiment=patterns
28+
29+
main() {
30+
bool b = 1 > 2;
31+
switch (b) {
32+
//^^^^^^
33+
// [analyzer] unspecified
34+
// [cfe] unspecified
35+
case true:
36+
}
37+
switch (b) {
38+
//^^^^^^
39+
// [analyzer] unspecified
40+
// [cfe] unspecified
41+
case false:
42+
print("false");
43+
break;
44+
}
45+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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 But switch statements must only be exhaustive when the matched
6+
/// value is an always-exhaustive type, defined as:
7+
/// - bool
8+
/// - Null
9+
/// - A enum type
10+
/// - A type whose declaration is marked sealed
11+
/// - T? where T is always-exhaustive
12+
/// - FutureOr<T> for some type T that is always-exhaustive
13+
/// - A record type whose fields all have always-exhaustive types
14+
/// - A type variable X with bound T where T is always-exhaustive
15+
/// - A promoted type variable X & T where T is always-exhaustive
16+
///
17+
/// All other types are not always-exhaustive. Then:
18+
/// - It is a compile-time error if the cases in a switch statement or switch
19+
/// collection element are not exhaustive and the static type of the matched
20+
/// value is an always-exhaustive type. There is no error if a switch
21+
/// statement is not exhaustive when the type is not an always-exhaustive type
22+
///
23+
/// @description Check that it is a compile-time error if a switch statement is
24+
/// not exhaustive. Test `null`
25+
/// @author [email protected]
26+
27+
// SharedOptions=--enable-experiment=patterns
28+
29+
main() {
30+
switch (null) {
31+
//^^^^^^
32+
// [analyzer] unspecified
33+
// [cfe] unspecified
34+
}
35+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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 But switch statements must only be exhaustive when the matched
6+
/// value is an always-exhaustive type, defined as:
7+
/// - bool
8+
/// - Null
9+
/// - A enum type
10+
/// - A type whose declaration is marked sealed
11+
/// - T? where T is always-exhaustive
12+
/// - FutureOr<T> for some type T that is always-exhaustive
13+
/// - A record type whose fields all have always-exhaustive types
14+
/// - A type variable X with bound T where T is always-exhaustive
15+
/// - A promoted type variable X & T where T is always-exhaustive
16+
///
17+
/// All other types are not always-exhaustive. Then:
18+
/// - It is a compile-time error if the cases in a switch statement or switch
19+
/// collection element are not exhaustive and the static type of the matched
20+
/// value is an always-exhaustive type. There is no error if a switch
21+
/// statement is not exhaustive when the type is not an always-exhaustive type
22+
///
23+
/// @description Check that it is a compile-time error if a switch statement is
24+
/// not exhaustive. Test an enum type
25+
/// @author [email protected]
26+
27+
// SharedOptions=--enable-experiment=patterns
28+
29+
enum E {
30+
e1,
31+
e2
32+
}
33+
34+
main() {
35+
E e = E.e1;
36+
switch (e) {
37+
//^^^^^^
38+
// [analyzer] unspecified
39+
// [cfe] unspecified
40+
case E.e1:
41+
}
42+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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 But switch statements must only be exhaustive when the matched
6+
/// value is an always-exhaustive type, defined as:
7+
/// - bool
8+
/// - Null
9+
/// - A enum type
10+
/// - A type whose declaration is marked sealed
11+
/// - T? where T is always-exhaustive
12+
/// - FutureOr<T> for some type T that is always-exhaustive
13+
/// - A record type whose fields all have always-exhaustive types
14+
/// - A type variable X with bound T where T is always-exhaustive
15+
/// - A promoted type variable X & T where T is always-exhaustive
16+
///
17+
/// All other types are not always-exhaustive. Then:
18+
/// - It is a compile-time error if the cases in a switch statement or switch
19+
/// collection element are not exhaustive and the static type of the matched
20+
/// value is an always-exhaustive type. There is no error if a switch
21+
/// statement is not exhaustive when the type is not an always-exhaustive type
22+
///
23+
/// @description Check that it is a compile-time error if a switch statement is
24+
/// not exhaustive. Test a type whose declaration is marked sealed
25+
/// @author [email protected]
26+
27+
// SharedOptions=--enable-experiment=patterns,class-modifiers
28+
29+
sealed class Sealed {}
30+
class C1 extends Sealed {}
31+
class C2 extends Sealed {}
32+
33+
main() {
34+
Sealed s = C1();
35+
switch (s) {
36+
//^^^^^^
37+
// [analyzer] unspecified
38+
// [cfe] unspecified
39+
case C1 _:
40+
}
41+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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 But switch statements must only be exhaustive when the matched
6+
/// value is an always-exhaustive type, defined as:
7+
/// - bool
8+
/// - Null
9+
/// - A enum type
10+
/// - A type whose declaration is marked sealed
11+
/// - T? where T is always-exhaustive
12+
/// - FutureOr<T> for some type T that is always-exhaustive
13+
/// - A record type whose fields all have always-exhaustive types
14+
/// - A type variable X with bound T where T is always-exhaustive
15+
/// - A promoted type variable X & T where T is always-exhaustive
16+
///
17+
/// All other types are not always-exhaustive. Then:
18+
/// - It is a compile-time error if the cases in a switch statement or switch
19+
/// collection element are not exhaustive and the static type of the matched
20+
/// value is an always-exhaustive type. There is no error if a switch
21+
/// statement is not exhaustive when the type is not an always-exhaustive type
22+
///
23+
/// @description Check that it is a compile-time error if a switch statement is
24+
/// not exhaustive. Test a type `T?` where `T` is always-exhaustive
25+
/// @author [email protected]
26+
27+
// SharedOptions=--enable-experiment=patterns,class-modifiers
28+
29+
main() {
30+
bool? b = 1 > 2;
31+
if (b) {
32+
b = null;
33+
}
34+
switch (b) {
35+
//^^^^^^
36+
// [analyzer] unspecified
37+
// [cfe] unspecified
38+
case true:
39+
case false:
40+
}
41+
switch (b) {
42+
//^^^^^^
43+
// [analyzer] unspecified
44+
// [cfe] unspecified
45+
case true:
46+
case null:
47+
}
48+
}
Lines changed: 45 additions & 0 deletions
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 But switch statements must only be exhaustive when the matched
6+
/// value is an always-exhaustive type, defined as:
7+
/// - bool
8+
/// - Null
9+
/// - A enum type
10+
/// - A type whose declaration is marked sealed
11+
/// - T? where T is always-exhaustive
12+
/// - FutureOr<T> for some type T that is always-exhaustive
13+
/// - A record type whose fields all have always-exhaustive types
14+
/// - A type variable X with bound T where T is always-exhaustive
15+
/// - A promoted type variable X & T where T is always-exhaustive
16+
///
17+
/// All other types are not always-exhaustive. Then:
18+
/// - It is a compile-time error if the cases in a switch statement or switch
19+
/// collection element are not exhaustive and the static type of the matched
20+
/// value is an always-exhaustive type. There is no error if a switch
21+
/// statement is not exhaustive when the type is not an always-exhaustive type
22+
///
23+
/// @description Check that it is a compile-time error if a switch statement is
24+
/// not exhaustive. Test a type `FutureOr<T>` for `T` that is always-exhaustive
25+
/// @author [email protected]
26+
27+
// SharedOptions=--enable-experiment=patterns
28+
29+
import "dart:async";
30+
31+
main() {
32+
FutureOr<bool> fo = true;
33+
switch (fo) {
34+
//^^^^^^
35+
// [analyzer] unspecified
36+
// [cfe] unspecified
37+
case bool _:
38+
}
39+
switch (fo) {
40+
//^^^^^^
41+
// [analyzer] unspecified
42+
// [cfe] unspecified
43+
case Future<bool> _:
44+
}
45+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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 But switch statements must only be exhaustive when the matched
6+
/// value is an always-exhaustive type, defined as:
7+
/// - bool
8+
/// - Null
9+
/// - A enum type
10+
/// - A type whose declaration is marked sealed
11+
/// - T? where T is always-exhaustive
12+
/// - FutureOr<T> for some type T that is always-exhaustive
13+
/// - A record type whose fields all have always-exhaustive types
14+
/// - A type variable X with bound T where T is always-exhaustive
15+
/// - A promoted type variable X & T where T is always-exhaustive
16+
///
17+
/// All other types are not always-exhaustive. Then:
18+
/// - It is a compile-time error if the cases in a switch statement or switch
19+
/// collection element are not exhaustive and the static type of the matched
20+
/// value is an always-exhaustive type. There is no error if a switch
21+
/// statement is not exhaustive when the type is not an always-exhaustive type
22+
///
23+
/// @description Check that it is a compile-time error if a switch statement is
24+
/// not exhaustive. Test a record type whose fields all have always-exhaustive
25+
/// types
26+
/// @author [email protected]
27+
28+
// SharedOptions=--enable-experiment=patterns,records
29+
30+
test((bool, {bool b}) r) {
31+
switch (r) {
32+
//^^^^^^
33+
// [analyzer] unspecified
34+
// [cfe] unspecified
35+
case (true, b: true):
36+
case (true, b: false):
37+
case (false, b: true):
38+
}
39+
}
40+
41+
main() {
42+
test((true, b: false));
43+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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 But switch statements must only be exhaustive when the matched
6+
/// value is an always-exhaustive type, defined as:
7+
/// - bool
8+
/// - Null
9+
/// - A enum type
10+
/// - A type whose declaration is marked sealed
11+
/// - T? where T is always-exhaustive
12+
/// - FutureOr<T> for some type T that is always-exhaustive
13+
/// - A record type whose fields all have always-exhaustive types
14+
/// - A type variable X with bound T where T is always-exhaustive
15+
/// - A promoted type variable X & T where T is always-exhaustive
16+
///
17+
/// All other types are not always-exhaustive. Then:
18+
/// - It is a compile-time error if the cases in a switch statement or switch
19+
/// collection element are not exhaustive and the static type of the matched
20+
/// value is an always-exhaustive type. There is no error if a switch
21+
/// statement is not exhaustive when the type is not an always-exhaustive type
22+
///
23+
/// @description Check that it is a compile-time error if a switch statement is
24+
/// not exhaustive. Test a type variable `X` with bound `T` where `T` is
25+
/// always-exhaustive
26+
/// @author [email protected]
27+
/// @issue 51887
28+
29+
// SharedOptions=--enable-experiment=patterns,class-modifiers
30+
31+
sealed class Sealed {}
32+
class C1 extends Sealed {}
33+
class C2 extends Sealed {}
34+
35+
test1<T extends Sealed>() {
36+
switch (T) {
37+
//^^^^^^
38+
// [analyzer] unspecified
39+
// [cfe] unspecified
40+
case C1:
41+
}
42+
}
43+
44+
test2<T extends bool?>() {
45+
switch (T) {
46+
//^^^^^^
47+
// [analyzer] unspecified
48+
// [cfe] unspecified
49+
case bool:
50+
}
51+
}
52+
53+
main() {
54+
test1<C1>();
55+
test2<bool>();
56+
}

0 commit comments

Comments
 (0)