[Typed throws] Location based lookup for the thrown error type

Introduce a new API to find the AST node that catches or rethrows an
error thrown from the given source location. Use it to determine the
thrown error type to use for type checking a `throw` statement, which
begins as `any Error` within a `do..catch` and is later refined.
This commit is contained in:
Doug Gregor
2023-10-15 14:33:04 -07:00
parent 7e9013dd52
commit 3dd4df2351
9 changed files with 226 additions and 9 deletions

View File

@@ -11398,3 +11398,32 @@ MacroDiscriminatorContext::getParentOf(FreestandingMacroExpansion *expansion) {
return getParentOf(
expansion->getPoundLoc(), expansion->getDeclContext());
}
llvm::Optional<Type>
CatchNode::getThrownErrorTypeInContext(ASTContext &ctx) const {
if (auto func = dyn_cast<AbstractFunctionDecl *>()) {
if (auto thrownError = func->getEffectiveThrownErrorType())
return func->mapTypeIntoContext(*thrownError);
return llvm::None;
}
if (auto closure = dyn_cast<AbstractClosureExpr *>()) {
if (closure->getType())
return closure->getEffectiveThrownType();
// FIXME: Should we lazily compute this?
return llvm::None;
}
auto doCatch = get<DoCatchStmt *>();
if (auto thrownError = doCatch->getCaughtErrorType()) {
if (thrownError->isNever())
return llvm::None;
return thrownError;
}
// If we haven't computed the error type yet, do so now.
return ctx.getErrorExistentialType();
}