@@ -820,11 +820,8 @@ class ApplyClassifier {
820
820
class Context {
821
821
public:
822
822
enum class Kind : uint8_t {
823
- // / A context that handles errors.
824
- Handled,
825
-
826
- // / A non-throwing function.
827
- NonThrowingFunction,
823
+ // / A context that potentially handles errors or async calls.
824
+ PotentiallyHandled,
828
825
829
826
// / A default argument expression.
830
827
DefaultArgument,
@@ -859,17 +856,24 @@ class Context {
859
856
860
857
Kind TheKind;
861
858
Optional<AnyFunctionRef> Function;
859
+ bool HandlesErrors = false ;
862
860
bool IsNonExhaustiveCatch = false ;
863
861
bool DiagnoseErrorOnTry = false ;
864
862
InterpolatedStringLiteralExpr *InterpolatedString = nullptr ;
865
863
866
- explicit Context (Kind kind, Optional<AnyFunctionRef> function = None)
867
- : TheKind(kind), Function(function) {}
864
+ explicit Context (Kind kind)
865
+ : TheKind(kind), Function(None), HandlesErrors(false ) {
866
+ assert (TheKind != Kind::PotentiallyHandled);
867
+ }
868
+
869
+ explicit Context (bool handlesErrors, Optional<AnyFunctionRef> function)
870
+ : TheKind(Kind::PotentiallyHandled), Function(function),
871
+ HandlesErrors(handlesErrors) { }
868
872
869
873
public:
870
874
// / Whether this is a function that rethrows.
871
875
bool isRethrows () const {
872
- if (getKind () != Kind::Handled )
876
+ if (!HandlesErrors )
873
877
return false ;
874
878
875
879
if (!Function)
@@ -895,12 +899,12 @@ class Context {
895
899
}
896
900
897
901
static Context getHandled () {
898
- return Context (Kind::Handled );
902
+ return Context (/* handlesErrors= */ true , None );
899
903
}
900
904
901
905
static Context forTopLevelCode (TopLevelCodeDecl *D) {
902
- // Top-level code implicitly handles errors.
903
- return Context (Kind::Handled );
906
+ // Top-level code implicitly handles errors and 'async' calls .
907
+ return Context (/* handlesErrors= */ true , None );
904
908
}
905
909
906
910
static Context forFunction (AbstractFunctionDecl *D) {
@@ -920,8 +924,8 @@ class Context {
920
924
}
921
925
}
922
926
923
- return Context ( D->hasThrows () ? Kind::Handled : Kind::NonThrowingFunction,
924
- AnyFunctionRef (D));
927
+ bool handlesErrors = D->hasThrows ();
928
+ return Context (handlesErrors, AnyFunctionRef (D));
925
929
}
926
930
927
931
static Context forDeferBody () {
@@ -951,9 +955,7 @@ class Context {
951
955
closureTypeThrows = fnType->isThrowing ();
952
956
}
953
957
954
- return Context (closureTypeThrows ? Kind::Handled
955
- : Kind::NonThrowingFunction,
956
- AnyFunctionRef (E));
958
+ return Context (closureTypeThrows, AnyFunctionRef (E));
957
959
}
958
960
959
961
static Context forCatchPattern (CaseStmt *S) {
@@ -977,7 +979,7 @@ class Context {
977
979
Kind getKind () const { return TheKind; }
978
980
979
981
bool handlesNothing () const {
980
- return getKind () != Kind::Handled ;
982
+ return !HandlesErrors ;
981
983
}
982
984
bool handles (ThrowingKind errorKind) const {
983
985
switch (errorKind) {
@@ -986,12 +988,12 @@ class Context {
986
988
987
989
// A call that's rethrowing-only can be handled by 'rethrows'.
988
990
case ThrowingKind::RethrowingOnly:
989
- return getKind () == Kind::Handled ;
991
+ return HandlesErrors ;
990
992
991
993
// An operation that always throws can only be handled by an
992
994
// all-handling context.
993
995
case ThrowingKind::Throws:
994
- return getKind () == Kind::Handled && !isRethrows ();
996
+ return HandlesErrors && !isRethrows ();
995
997
}
996
998
llvm_unreachable (" bad error kind" );
997
999
}
@@ -1125,18 +1127,7 @@ class Context {
1125
1127
bool isTryCovered,
1126
1128
const PotentialThrowReason &reason) {
1127
1129
switch (getKind ()) {
1128
- case Kind::Handled:
1129
- if (isRethrows ()) {
1130
- diagnoseThrowInLegalContext (Diags, E, isTryCovered, reason,
1131
- diag::throw_in_rethrows_function,
1132
- diag::throwing_call_in_rethrows_function,
1133
- diag::tryless_throwing_call_in_rethrows_function);
1134
- return ;
1135
- }
1136
-
1137
- llvm_unreachable (" throw site is handled!" );
1138
-
1139
- case Kind::NonThrowingFunction:
1130
+ case Kind::PotentiallyHandled:
1140
1131
if (IsNonExhaustiveCatch) {
1141
1132
diagnoseThrowInLegalContext (Diags, E, isTryCovered, reason,
1142
1133
diag::throw_in_nonexhaustive_catch,
@@ -1153,6 +1144,14 @@ class Context {
1153
1144
return ;
1154
1145
}
1155
1146
1147
+ if (isRethrows ()) {
1148
+ diagnoseThrowInLegalContext (Diags, E, isTryCovered, reason,
1149
+ diag::throw_in_rethrows_function,
1150
+ diag::throwing_call_in_rethrows_function,
1151
+ diag::tryless_throwing_call_in_rethrows_function);
1152
+ return ;
1153
+ }
1154
+
1156
1155
diagnoseThrowInLegalContext (Diags, E, isTryCovered, reason,
1157
1156
diag::throw_in_nonthrowing_function,
1158
1157
diag::throwing_call_unhandled,
@@ -1191,10 +1190,7 @@ class Context {
1191
1190
1192
1191
void diagnoseUnhandledTry (DiagnosticEngine &Diags, TryExpr *E) {
1193
1192
switch (getKind ()) {
1194
- case Kind::Handled:
1195
- llvm_unreachable (" try is handled!" );
1196
-
1197
- case Kind::NonThrowingFunction:
1193
+ case Kind::PotentiallyHandled:
1198
1194
if (DiagnoseErrorOnTry) {
1199
1195
Diags.diagnose (
1200
1196
E->getTryLoc (),
0 commit comments