@@ -820,11 +820,8 @@ class ApplyClassifier {
820820class Context {
821821public:
822822 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,
828825
829826 // / A default argument expression.
830827 DefaultArgument,
@@ -859,17 +856,24 @@ class Context {
859856
860857 Kind TheKind;
861858 Optional<AnyFunctionRef> Function;
859+ bool HandlesErrors = false ;
862860 bool IsNonExhaustiveCatch = false ;
863861 bool DiagnoseErrorOnTry = false ;
864862 InterpolatedStringLiteralExpr *InterpolatedString = nullptr ;
865863
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) { }
868872
869873public:
870874 // / Whether this is a function that rethrows.
871875 bool isRethrows () const {
872- if (getKind () != Kind::Handled )
876+ if (!HandlesErrors )
873877 return false ;
874878
875879 if (!Function)
@@ -895,12 +899,12 @@ class Context {
895899 }
896900
897901 static Context getHandled () {
898- return Context (Kind::Handled );
902+ return Context (/* handlesErrors= */ true , None );
899903 }
900904
901905 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 );
904908 }
905909
906910 static Context forFunction (AbstractFunctionDecl *D) {
@@ -920,8 +924,8 @@ class Context {
920924 }
921925 }
922926
923- return Context ( D->hasThrows () ? Kind::Handled : Kind::NonThrowingFunction,
924- AnyFunctionRef (D));
927+ bool handlesErrors = D->hasThrows ();
928+ return Context (handlesErrors, AnyFunctionRef (D));
925929 }
926930
927931 static Context forDeferBody () {
@@ -951,9 +955,7 @@ class Context {
951955 closureTypeThrows = fnType->isThrowing ();
952956 }
953957
954- return Context (closureTypeThrows ? Kind::Handled
955- : Kind::NonThrowingFunction,
956- AnyFunctionRef (E));
958+ return Context (closureTypeThrows, AnyFunctionRef (E));
957959 }
958960
959961 static Context forCatchPattern (CaseStmt *S) {
@@ -977,7 +979,7 @@ class Context {
977979 Kind getKind () const { return TheKind; }
978980
979981 bool handlesNothing () const {
980- return getKind () != Kind::Handled ;
982+ return !HandlesErrors ;
981983 }
982984 bool handles (ThrowingKind errorKind) const {
983985 switch (errorKind) {
@@ -986,12 +988,12 @@ class Context {
986988
987989 // A call that's rethrowing-only can be handled by 'rethrows'.
988990 case ThrowingKind::RethrowingOnly:
989- return getKind () == Kind::Handled ;
991+ return HandlesErrors ;
990992
991993 // An operation that always throws can only be handled by an
992994 // all-handling context.
993995 case ThrowingKind::Throws:
994- return getKind () == Kind::Handled && !isRethrows ();
996+ return HandlesErrors && !isRethrows ();
995997 }
996998 llvm_unreachable (" bad error kind" );
997999 }
@@ -1125,18 +1127,7 @@ class Context {
11251127 bool isTryCovered,
11261128 const PotentialThrowReason &reason) {
11271129 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:
11401131 if (IsNonExhaustiveCatch) {
11411132 diagnoseThrowInLegalContext (Diags, E, isTryCovered, reason,
11421133 diag::throw_in_nonexhaustive_catch,
@@ -1153,6 +1144,14 @@ class Context {
11531144 return ;
11541145 }
11551146
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+
11561155 diagnoseThrowInLegalContext (Diags, E, isTryCovered, reason,
11571156 diag::throw_in_nonthrowing_function,
11581157 diag::throwing_call_unhandled,
@@ -1191,10 +1190,7 @@ class Context {
11911190
11921191 void diagnoseUnhandledTry (DiagnosticEngine &Diags, TryExpr *E) {
11931192 switch (getKind ()) {
1194- case Kind::Handled:
1195- llvm_unreachable (" try is handled!" );
1196-
1197- case Kind::NonThrowingFunction:
1193+ case Kind::PotentiallyHandled:
11981194 if (DiagnoseErrorOnTry) {
11991195 Diags.diagnose (
12001196 E->getTryLoc (),
0 commit comments