Skip to content

Commit ea8217a

Browse files
committed
[Effects handling] Collapse "Handled" and "NonThrowingFunction" kinds.
Finish eliminating error-handling-specific information from the "kind" of the effects-handling context, so that it only distinguishes between "potentially handles effects" and "never handles effects". Use queries for specific issues (e.g., "handles errors") instead.
1 parent 524887b commit ea8217a

File tree

1 file changed

+31
-35
lines changed

1 file changed

+31
-35
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -820,11 +820,8 @@ class ApplyClassifier {
820820
class Context {
821821
public:
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

869873
public:
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

Comments
 (0)