Skip to content

Commit 05a4a82

Browse files
committed
Tighten CatchNode from an AbstractClosureExpr to a ClosureExpr.
Only real closures can have thrown error types, so we can use the tighter bound for closures and simplify various CatchNode operations.
1 parent 010a412 commit 05a4a82

File tree

5 files changed

+35
-46
lines changed

5 files changed

+35
-46
lines changed

include/swift/AST/CatchNode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace swift {
2525
/// An AST node that represents a point where a thrown error can be caught and
2626
/// or rethrown, which includes functions do...catch statements.
2727
class CatchNode: public llvm::PointerUnion<
28-
AbstractFunctionDecl *, AbstractClosureExpr *, DoCatchStmt *, AnyTryExpr *
28+
AbstractFunctionDecl *, ClosureExpr *, DoCatchStmt *, AnyTryExpr *
2929
> {
3030
public:
3131
using PointerUnion::PointerUnion;

lib/AST/ASTScopeLookup.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -684,8 +684,9 @@ static std::pair<CatchNode, const BraceStmtScope *>
684684
getCatchNode(const ASTScopeImpl *scope) {
685685
// Closures introduce a catch scope for errors initiated in their body.
686686
if (auto closureParams = dyn_cast<ClosureParametersScope>(scope)) {
687-
return getCatchNodeBody(
688-
scope, const_cast<AbstractClosureExpr *>(closureParams->closureExpr));
687+
if (auto closure = dyn_cast<ClosureExpr>(closureParams->closureExpr)) {
688+
return getCatchNodeBody(scope, const_cast<ClosureExpr *>(closure));
689+
}
689690
}
690691

691692
// Functions introduce a catch scope for errors initiated in their body.

lib/AST/Decl.cpp

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11702,17 +11702,15 @@ CatchNode::getThrownErrorTypeInContext(DeclContext *dc) const {
1170211702
return llvm::None;
1170311703
}
1170411704

11705-
if (auto abstractClosure = dyn_cast<AbstractClosureExpr *>()) {
11706-
if (abstractClosure->getType())
11707-
return abstractClosure->getEffectiveThrownType();
11705+
if (auto closure = dyn_cast<ClosureExpr *>()) {
11706+
if (closure->getType())
11707+
return closure->getEffectiveThrownType();
1170811708

11709-
if (auto closure = llvm::dyn_cast<ClosureExpr>(abstractClosure)) {
11710-
if (Type thrownType = closure->getExplicitThrownType()) {
11711-
if (thrownType->isNever())
11712-
return llvm::None;
11709+
if (Type thrownType = closure->getExplicitThrownType()) {
11710+
if (thrownType->isNever())
11711+
return llvm::None;
1171311712

11714-
return thrownType;
11715-
}
11713+
return thrownType;
1171611714
}
1171711715

1171811716
return llvm::None;
@@ -11770,12 +11768,8 @@ bool ExplicitCaughtTypeRequest::isCached() const {
1177011768
}
1177111769

1177211770
// Closures with explicitly-written thrown types need the result cached.
11773-
if (auto abstractClosure = catchNode.dyn_cast<AbstractClosureExpr *>()) {
11774-
if (auto closure = dyn_cast<ClosureExpr>(abstractClosure)) {
11775-
return closure->ThrownType != nullptr;
11776-
}
11777-
11778-
return false;
11771+
if (auto closure = catchNode.dyn_cast<ClosureExpr *>()) {
11772+
return closure->ThrownType != nullptr;
1177911773
}
1178011774

1178111775
// Do..catch with explicitly-written thrown types need the result cached.
@@ -11801,8 +11795,7 @@ llvm::Optional<Type> ExplicitCaughtTypeRequest::getCachedResult() const {
1180111795
return nonnullTypeOrNone(func->ThrownType.getType());
1180211796
}
1180311797

11804-
if (auto abstractClosure = catchNode.dyn_cast<AbstractClosureExpr *>()) {
11805-
auto closure = cast<ClosureExpr>(abstractClosure);
11798+
if (auto closure = catchNode.dyn_cast<ClosureExpr *>()) {
1180611799
if (closure->ThrownType) {
1180711800
return nonnullTypeOrNone(closure->ThrownType->getInstanceType());
1180811801
}
@@ -11825,8 +11818,7 @@ void ExplicitCaughtTypeRequest::cacheResult(Type type) const {
1182511818
return;
1182611819
}
1182711820

11828-
if (auto abstractClosure = catchNode.dyn_cast<AbstractClosureExpr *>()) {
11829-
auto closure = cast<ClosureExpr>(abstractClosure);
11821+
if (auto closure = catchNode.dyn_cast<ClosureExpr *>()) {
1183011822
if (closure->ThrownType)
1183111823
closure->ThrownType->setType(MetatypeType::get(type));
1183211824
else

lib/Sema/CSSyntacticElement.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -927,10 +927,8 @@ class SyntacticElementConstraintGenerator
927927
if (catchNode) {
928928
// FIXME: Introduce something like getThrownErrorTypeInContext() for the
929929
// constraint solver.
930-
if (auto abstractClosure = catchNode.dyn_cast<AbstractClosureExpr *>()) {
931-
if (auto closure = dyn_cast<ClosureExpr>(abstractClosure)) {
932-
errorType = cs.getClosureType(closure)->getThrownError();
933-
}
930+
if (auto closure = catchNode.dyn_cast<ClosureExpr *>()) {
931+
errorType = cs.getClosureType(closure)->getThrownError();
934932
}
935933

936934
if (!errorType)

lib/Sema/TypeCheckType.cpp

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5697,28 +5697,26 @@ Type ExplicitCaughtTypeRequest::evaluate(
56975697
}
56985698

56995699
// Closures
5700-
if (auto abstractClosure = catchNode.dyn_cast<AbstractClosureExpr *>()) {
5701-
if (auto closure = dyn_cast<ClosureExpr>(abstractClosure)) {
5702-
assert(dc == closure && "Key mismatch for explicit caught type request");
5703-
5704-
// Explicit thrown error type.
5705-
if (auto thrownTypeRepr = closure->getExplicitThrownTypeRepr()) {
5706-
if (!ctx.LangOpts.hasFeature(Feature::TypedThrows)) {
5707-
ctx.Diags.diagnose(thrownTypeRepr->getLoc(),
5708-
diag::experimental_typed_throws);
5709-
}
5710-
5711-
return TypeResolution::resolveContextualType(
5712-
thrownTypeRepr, dc,
5713-
TypeResolutionOptions(TypeResolverContext::None),
5714-
/*unboundTyOpener*/ nullptr, PlaceholderType::get,
5715-
/*packElementOpener*/ nullptr);
5700+
if (auto closure = catchNode.dyn_cast<ClosureExpr *>()) {
5701+
assert(dc == closure && "Key mismatch for explicit caught type request");
5702+
5703+
// Explicit thrown error type.
5704+
if (auto thrownTypeRepr = closure->getExplicitThrownTypeRepr()) {
5705+
if (!ctx.LangOpts.hasFeature(Feature::TypedThrows)) {
5706+
ctx.Diags.diagnose(thrownTypeRepr->getLoc(),
5707+
diag::experimental_typed_throws);
57165708
}
57175709

5718-
// Explicit 'throws' implies that this throws 'any Error'.
5719-
if (closure->getThrowsLoc().isValid()) {
5720-
return ctx.getErrorExistentialType();
5721-
}
5710+
return TypeResolution::resolveContextualType(
5711+
thrownTypeRepr, dc,
5712+
TypeResolutionOptions(TypeResolverContext::None),
5713+
/*unboundTyOpener*/ nullptr, PlaceholderType::get,
5714+
/*packElementOpener*/ nullptr);
5715+
}
5716+
5717+
// Explicit 'throws' implies that this throws 'any Error'.
5718+
if (closure->getThrowsLoc().isValid()) {
5719+
return ctx.getErrorExistentialType();
57225720
}
57235721

57245722
// Thrown error type will be inferred.

0 commit comments

Comments
 (0)