@@ -979,9 +979,13 @@ bool Decl::preconcurrency() const {
979979}
980980
981981Type AbstractFunctionDecl::getThrownInterfaceType () const {
982+ if (!getThrownTypeRepr ())
983+ return ThrownType.getType ();
984+
985+ auto mutableThis = const_cast <AbstractFunctionDecl *>(this );
982986 return evaluateOrDefault (
983987 getASTContext ().evaluator ,
984- ThrownTypeRequest{ const_cast <AbstractFunctionDecl *>( this ) },
988+ ExplicitCaughtTypeRequest{mutableThis, mutableThis },
985989 Type ());
986990}
987991
@@ -11737,3 +11741,96 @@ CatchNode::getThrownErrorTypeInContext(DeclContext *dc) const {
1173711741
1173811742 llvm_unreachable (" Unhandled catch node kind" );
1173911743}
11744+
11745+ void swift::simple_display (llvm::raw_ostream &out, CatchNode catchNode) {
11746+ out << " catch node" ;
11747+ }
11748+
11749+ // ----------------------------------------------------------------------------//
11750+ // ExplicitCaughtTypeRequest computation.
11751+ // ----------------------------------------------------------------------------//
11752+ bool ExplicitCaughtTypeRequest::isCached () const {
11753+ auto catchNode = std::get<1 >(getStorage ());
11754+
11755+ // try? and try! never need to be cached.
11756+ if (catchNode.is <AnyTryExpr *>())
11757+ return false ;
11758+
11759+ // Functions with explicitly-written thrown types need the result cached.
11760+ if (auto func = catchNode.dyn_cast <AbstractFunctionDecl *>()) {
11761+ return func->ThrownType .getTypeRepr () != nullptr ;
11762+ }
11763+
11764+ // Closures with explicitly-written thrown types need the result cached.
11765+ if (auto abstractClosure = catchNode.dyn_cast <AbstractClosureExpr *>()) {
11766+ if (auto closure = dyn_cast<ClosureExpr>(abstractClosure)) {
11767+ return closure->ThrownType != nullptr ;
11768+ }
11769+
11770+ return false ;
11771+ }
11772+
11773+ // Do..catch with explicitly-written thrown types need the result cached.
11774+ if (auto doCatch = catchNode.dyn_cast <DoCatchStmt *>()) {
11775+ return doCatch->getThrowsLoc ().isValid ();
11776+ }
11777+
11778+ llvm_unreachable (" Unhandled catch node" );
11779+ }
11780+
11781+ llvm::Optional<Type> ExplicitCaughtTypeRequest::getCachedResult () const {
11782+ // Map a possibly-null Type to llvm::Optional<Type>.
11783+ auto nonnullTypeOrNone = [](Type type) -> llvm::Optional<Type> {
11784+ if (type.isNull ())
11785+ return llvm::None;
11786+
11787+ return type;
11788+ };
11789+
11790+ auto catchNode = std::get<1 >(getStorage ());
11791+
11792+ if (auto func = catchNode.dyn_cast <AbstractFunctionDecl *>()) {
11793+ return nonnullTypeOrNone (func->ThrownType .getType ());
11794+ }
11795+
11796+ if (auto abstractClosure = catchNode.dyn_cast <AbstractClosureExpr *>()) {
11797+ auto closure = cast<ClosureExpr>(abstractClosure);
11798+ if (closure->ThrownType ) {
11799+ return nonnullTypeOrNone (closure->ThrownType ->getInstanceType ());
11800+ }
11801+
11802+ return llvm::None;
11803+ }
11804+
11805+ if (auto doCatch = catchNode.dyn_cast <DoCatchStmt *>()) {
11806+ return nonnullTypeOrNone (doCatch->ThrownType .getType ());
11807+ }
11808+
11809+ llvm_unreachable (" Unhandled catch node" );
11810+ }
11811+
11812+ void ExplicitCaughtTypeRequest::cacheResult (Type type) const {
11813+ auto catchNode = std::get<1 >(getStorage ());
11814+
11815+ if (auto func = catchNode.dyn_cast <AbstractFunctionDecl *>()) {
11816+ func->ThrownType .setType (type);
11817+ return ;
11818+ }
11819+
11820+ if (auto abstractClosure = catchNode.dyn_cast <AbstractClosureExpr *>()) {
11821+ auto closure = cast<ClosureExpr>(abstractClosure);
11822+ if (closure->ThrownType )
11823+ closure->ThrownType ->setType (MetatypeType::get (type));
11824+ else
11825+ closure->ThrownType =
11826+ TypeExpr::createImplicit (type, type->getASTContext ());
11827+ return ;
11828+ }
11829+
11830+ if (auto doCatch = catchNode.dyn_cast <DoCatchStmt *>()) {
11831+ doCatch->ThrownType .setType (type);
11832+ return ;
11833+ }
11834+
11835+ llvm_unreachable (" Unhandled catch node" );
11836+ }
0 commit comments