blob: c3494adb9e331fcc7779e6823edb5c6ab2c98994 [file] [log] [blame] [edit]
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// @assertion To tell if the set of cases in a switch statement or expression
/// are exhaustive over the matched value type:
/// 1. Lift the matched value type to a space union value.
/// 2. Discard any cases that have guards. Since static analysis can't tell when
/// a guard might evaluate to false, any case with a guard doesn't reliably
/// match values and so can't help prove exhaustiveness.
/// 3. Lift the remaining case patterns to a set of space unions cases.
/// 4. The switch is exhaustive if is-exhaustive with value and cases is true
/// and false otherwise.
///
/// @description Check that any cases with guards are ignored when calculating
/// an exhaustiveness
/// @author sgrekhov22@gmail.com
import "exhaustiveness_lib.dart";
String testBool1(bool b) {
switch (b) {
//^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
case true:
return "true";
case false when b == false:
return "false";
}
}
String testBool2(bool b) => switch (b) {
// ^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
true when b == true => "true",
false => "false"
};
String testEnum1(Suit suit) {
switch (suit) {
//^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
case Suit.club:
case Suit.diamond:
case Suit.heart when suit == Suit.heart:
case Suit.spade:
return "exhaustive";
}
// There is no return statement here, switch statement is not exhaustive, so an
// error above occurs because function return type cannot be null
}
String testEnum2(Suit suit) => switch (suit) {
// ^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
Suit.club => "club",
Suit.diamond => "diamond",
Suit.heart when suit == Suit.heart => "heart",
Suit.spade => "spade"
};
String testSealed1(Card card) {
switch (card) {
//^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
case Pip _ when true:
return "Pip";
case Face _:
return "Face";
}
}
String testSealed2(Card card) => switch (card) {
// ^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
Pip _ => "Pip",
Face _ when true => "Face"
};
main() {
testBool1(true);
testBool2(false);
testEnum1(Suit.club);
testEnum2(Suit.club);
testSealed1(Jack(Suit.club));
testSealed2(Jack(Suit.club));
}