blob: e2fa7b2af457766587e13606b66b136361c5eed7 [file] [log] [blame]
// 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.
sealed class A<X> {}
class B<Y> extends A<Y> {}
class C extends A<int> {}
class D<Z, W> extends A<W> {}
enum Enum { a, b }
void exhaustiveSwitchGeneric<T1>(A<T1> a) {
// TODO(johnniwinther): Room for improvement here. We could recognized the
// direct passing of type variables in D.
/*
checkingOrder={A<T1>,B<T1>,C,D<dynamic, dynamic>},
error=non-exhaustive:D<dynamic, dynamic>(),
subtypes={B<T1>,C,D<dynamic, dynamic>},
type=A<T1>
*/
switch (a) {
/*space=B<T1>*/
case B<T1> b:
print('B');
break;
/*space=C*/
case C c:
print('C');
break;
/*space=D<dynamic, T1>*/
case D<dynamic, T1> d:
print('D');
break;
}
}
void exhaustiveSwitchGenericCatchAll<T2>(A<T2> a) {
/*
checkingOrder={A<T2>,B<T2>,C,D<dynamic, dynamic>},
subtypes={B<T2>,C,D<dynamic, dynamic>},
type=A<T2>
*/
switch (a) {
/*space=B<T2>*/
case B<T2> b:
print('B');
break;
/*space=D<dynamic, T2>*/
case D<dynamic, T2> d:
print('D');
break;
/*space=A<T2>*/
case A<T2> _:
print('_');
break;
}
}
void exhaustiveSwitchGenericBounded<T3 extends String>(A<T3> a) {
// TODO(johnniwinther): Room for improvement here. We could recognized the
// direct passing of type variables in D.
/*
checkingOrder={A<T3>,B<T3>,D<dynamic, dynamic>},
error=non-exhaustive:D<dynamic, dynamic>(),
subtypes={B<T3>,D<dynamic, dynamic>},
type=A<T3>
*/
switch (a) {
/*space=B<T3>*/
case B<T3> b:
print('B');
break;
/*space=D<dynamic, T3>*/
case D<dynamic, T3> d:
print('D');
break;
}
}
void nonExhaustiveSwitchWrongGeneric1<T4, S4>(A<T4> a) {
/*
checkingOrder={A<T4>,B<T4>,C,D<dynamic, dynamic>},
error=non-exhaustive:B<T4>();D<dynamic, dynamic>(),
subtypes={B<T4>,C,D<dynamic, dynamic>},
type=A<T4>
*/
switch (a) {
/*space=B<S4>*/
case B<S4> b:
print('B');
break;
/*space=C*/
case C c:
print('C');
break;
/*space=D<dynamic, T4>*/
case D<dynamic, T4> d:
print('D');
break;
}
}
void nonExhaustiveSwitchWrongGeneric2<T5, S5>(A<T5> a) {
/*
checkingOrder={A<T5>,B<T5>,C,D<dynamic, dynamic>},
error=non-exhaustive:D<dynamic, dynamic>(),
subtypes={B<T5>,C,D<dynamic, dynamic>},
type=A<T5>
*/
switch (a) {
/*space=B<T5>*/
case B<T5> b:
print('B');
break;
/*space=C*/
case C c:
print('C');
break;
/*space=D<dynamic, S5>*/
case D<dynamic, S5> d:
print('D');
break;
}
}
void exhaustiveSwitch3(A<String> a) {
// TODO(johnniwinther): Room for improvement here. We could recognized the
// direct passing of type variables in D.
/*
checkingOrder={A<String>,B<String>,D<dynamic, dynamic>},
error=non-exhaustive:D<dynamic, dynamic>(),
subtypes={B<String>,D<dynamic, dynamic>},
type=A<String>
*/
switch (a) {
/*space=B<String>*/
case B<String> b:
print('B');
break;
/*space=D<dynamic, String>*/
case D<dynamic, String> d:
print('D');
break;
}
}
void nonExhaustiveSwitch1(A<int> a) {
/*
checkingOrder={A<int>,B<int>,C,D<dynamic, dynamic>},
error=non-exhaustive:D<dynamic, dynamic>(),
subtypes={B<int>,C,D<dynamic, dynamic>},
type=A<int>
*/
switch (a) {
/*space=B<int>*/
case B<int> b:
print('B');
break;
/*space=C*/
case C c:
print('C');
break;
}
}
void nonExhaustiveSwitch2(A<int> a) {
/*
checkingOrder={A<int>,B<int>,C,D<dynamic, dynamic>},
error=non-exhaustive:B<int>();D<dynamic, dynamic>(),
subtypes={B<int>,C,D<dynamic, dynamic>},
type=A<int>
*/
switch (a) {
/*space=C*/ case C c:
print('C');
break;
/*space=D<dynamic, int>*/ case D<dynamic, int> d:
print('D');
break;
}
}
void nonExhaustiveSwitch3(A<num> a) {
/*
checkingOrder={A<num>,B<num>,C,D<dynamic, dynamic>},
error=non-exhaustive:D<dynamic, dynamic>(),
subtypes={B<num>,C,D<dynamic, dynamic>},
type=A<num>
*/
switch (a) {
/*space=B<num>*/
case B<num> b:
print('B');
break;
/*space=C*/
case C c:
print('C');
break;
/*space=D<num, num>*/
case D<num, num> d:
print('D');
break;
}
}
void nonExhaustiveSwitchWithDefault(A<dynamic> a) {
/*
checkingOrder={A<dynamic>,B<dynamic>,C,D<dynamic, dynamic>},
subtypes={B<dynamic>,C,D<dynamic, dynamic>},
type=A<dynamic>
*/
switch (a) {
/*space=C*/
case C c:
print('C');
break;
default:
print('default');
break;
}
}
void exhaustiveNullableSwitch(A<int>? a) {
// TODO(johnniwinther): Room for improvement here. We could recognized the
// direct passing of type variables in D.
/*
checkingOrder={A<int>?,A<int>,Null,B<int>,C,D<dynamic, dynamic>},
error=non-exhaustive:D<dynamic, dynamic>(),
expandedSubtypes={B<int>,C,D<dynamic, dynamic>,Null},
subtypes={A<int>,Null},
type=A<int>?
*/
switch (a) {
/*space=B<int>*/
case B<int> b:
print('B');
break;
/*space=C*/
case C c:
print('C');
break;
/*space=D<dynamic, int>*/
case D<dynamic, int> d:
print('D');
break;
/*space=Null*/
case null:
print('null');
break;
}
}
void nonExhaustiveNullableSwitch1(A<int>? a) {
/*
checkingOrder={A<int>?,A<int>,Null,B<int>,C,D<dynamic, dynamic>},
error=non-exhaustive:null,
expandedSubtypes={B<int>,C,D<dynamic, dynamic>,Null},
subtypes={A<int>,Null},
type=A<int>?
*/
switch (a) {
/*space=A<int>*/
case A<int> a:
print('A');
break;
}
}
void nonExhaustiveNullableSwitch2(A<int>? a) {
/*
checkingOrder={A<int>?,A<int>,Null,B<int>,C,D<dynamic, dynamic>},
error=non-exhaustive:D<dynamic, dynamic>(),
expandedSubtypes={B<int>,C,D<dynamic, dynamic>,Null},
subtypes={A<int>,Null},
type=A<int>?
*/
switch (a) {
/*space=B<int>*/
case B<int> b:
print('B');
break;
/*space=C*/
case C c:
print('C');
break;
/*space=Null*/
case null:
print('null');
break;
}
}
void unreachableCase1(A<int> a) {
/*
checkingOrder={A<int>,B<int>,C,D<dynamic, dynamic>},
subtypes={B<int>,C,D<dynamic, dynamic>},
type=A<int>
*/
switch (a) {
/*space=B<int>*/
case B<int> b:
print('B');
break;
/*space=C*/
case C c:
print('C');
break;
/*space=D<dynamic, int>*/
case D<dynamic, int> d:
print('D');
break;
/*space=A<int>*/
case A a:
print('A');
break;
}
}
void unreachableCase2(A<int> a) {
// TODO(johnniwinther): Should we avoid the unreachable error here?
/*
checkingOrder={A<int>,B<int>,C,D<dynamic, dynamic>},
subtypes={B<int>,C,D<dynamic, dynamic>},
type=A<int>
*/
switch (a) {
/*space=A<int>*/
case A<int> a:
print('A');
break;
/*space=Null*/
case null:
print('null');
break;
}
}
void unreachableCase3(A<int>? a) {
/*
checkingOrder={A<int>?,A<int>,Null,B<int>,C,D<dynamic, dynamic>},
expandedSubtypes={B<int>,C,D<dynamic, dynamic>,Null},
subtypes={A<int>,Null},
type=A<int>?
*/
switch (a) {
/*space=A<int>*/
case A<int> a:
print('A');
break;
/*space=Null*/
case null:
print('null #1');
break;
/*
error=unreachable,
space=Null
*/
case null:
print('null #2');
break;
}
}