@@ -1718,14 +1718,15 @@ class Context {
17181718private:
17191719 static Context getContextForPatternBinding (PatternBindingDecl *pbd) {
17201720 if (!pbd->isStatic () && pbd->getDeclContext ()->isTypeContext ()) {
1721- return Context (Kind::IVarInitializer);
1721+ return Context (Kind::IVarInitializer, pbd-> getDeclContext () );
17221722 } else {
1723- return Context (Kind::GlobalVarInitializer);
1723+ return Context (Kind::GlobalVarInitializer, pbd-> getDeclContext () );
17241724 }
17251725 }
17261726
17271727 Kind TheKind;
17281728 llvm::Optional<AnyFunctionRef> Function;
1729+ DeclContext *DC;
17291730 bool HandlesErrors = false ;
17301731 bool HandlesAsync = false ;
17311732
@@ -1736,14 +1737,15 @@ class Context {
17361737 bool DiagnoseErrorOnTry = false ;
17371738 InterpolatedStringLiteralExpr *InterpolatedString = nullptr ;
17381739
1739- explicit Context (Kind kind)
1740- : TheKind(kind), Function(llvm::None), HandlesErrors(false ) {
1740+ explicit Context (Kind kind, DeclContext *dc )
1741+ : TheKind(kind), Function(llvm::None), DC(dc), HandlesErrors(false ) {
17411742 assert (TheKind != Kind::PotentiallyHandled);
17421743 }
17431744
17441745 explicit Context (bool handlesErrors, bool handlesAsync,
1745- llvm::Optional<AnyFunctionRef> function)
1746- : TheKind(Kind::PotentiallyHandled), Function(function),
1746+ llvm::Optional<AnyFunctionRef> function,
1747+ DeclContext *dc)
1748+ : TheKind(Kind::PotentiallyHandled), Function(function), DC(dc),
17471749 HandlesErrors(handlesErrors), HandlesAsync(handlesAsync) {}
17481750
17491751public:
@@ -1820,7 +1822,7 @@ class Context {
18201822 static Context forTopLevelCode (TopLevelCodeDecl *D) {
18211823 // Top-level code implicitly handles errors.
18221824 return Context (/* handlesErrors=*/ true ,
1823- /* handlesAsync=*/ D->isAsyncContext (), llvm::None);
1825+ /* handlesAsync=*/ D->isAsyncContext (), llvm::None, D );
18241826 }
18251827
18261828 static Context forFunction (AbstractFunctionDecl *D) {
@@ -1840,20 +1842,20 @@ class Context {
18401842 }
18411843 }
18421844
1843- return Context (D->hasThrows (), D->isAsyncContext (), AnyFunctionRef (D));
1845+ return Context (D->hasThrows (), D->isAsyncContext (), AnyFunctionRef (D), D );
18441846 }
18451847
1846- static Context forDeferBody () {
1847- return Context (Kind::DeferBody);
1848+ static Context forDeferBody (DeclContext *dc ) {
1849+ return Context (Kind::DeferBody, dc );
18481850 }
18491851
18501852 static Context forInitializer (Initializer *init) {
18511853 if (isa<DefaultArgumentInitializer>(init)) {
1852- return Context (Kind::DefaultArgument);
1854+ return Context (Kind::DefaultArgument, init );
18531855 }
18541856
18551857 if (isa<PropertyWrapperInitializer>(init)) {
1856- return Context (Kind::PropertyWrapper);
1858+ return Context (Kind::PropertyWrapper, init );
18571859 }
18581860
18591861 auto *binding = cast<PatternBindingInitializer>(init)->getBinding ();
@@ -1863,7 +1865,7 @@ class Context {
18631865 }
18641866
18651867 static Context forEnumElementInitializer (EnumElementDecl *elt) {
1866- return Context (Kind::EnumElementInitializer);
1868+ return Context (Kind::EnumElementInitializer, elt );
18671869 }
18681870
18691871 static Context forClosure (AbstractClosureExpr *E) {
@@ -1877,15 +1879,15 @@ class Context {
18771879 }
18781880 }
18791881
1880- return Context (closureTypeThrows, closureTypeIsAsync, AnyFunctionRef (E));
1882+ return Context (closureTypeThrows, closureTypeIsAsync, AnyFunctionRef (E), E );
18811883 }
18821884
1883- static Context forCatchPattern (CaseStmt *S) {
1884- return Context (Kind::CatchPattern);
1885+ static Context forCatchPattern (CaseStmt *S, DeclContext *dc ) {
1886+ return Context (Kind::CatchPattern, dc );
18851887 }
18861888
1887- static Context forCatchGuard (CaseStmt *S) {
1888- return Context (Kind::CatchGuard);
1889+ static Context forCatchGuard (CaseStmt *S, DeclContext *dc ) {
1890+ return Context (Kind::CatchGuard, dc );
18891891 }
18901892
18911893 static Context forPatternBinding (PatternBindingDecl *binding) {
@@ -1909,6 +1911,8 @@ class Context {
19091911
19101912 Kind getKind () const { return TheKind; }
19111913
1914+ DeclContext *getDeclContext () const { return DC; }
1915+
19121916 bool handlesThrows (ConditionalEffectKind errorKind) const {
19131917 switch (errorKind) {
19141918 case ConditionalEffectKind::None:
@@ -2587,6 +2591,19 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
25872591 }
25882592 };
25892593
2594+ // / Retrieve the type of the error that can be caught when an error is
2595+ // / thrown from the given location.
2596+ Type getCaughtErrorTypeAt (SourceLoc loc) {
2597+ auto module = CurContext.getDeclContext ()->getParentModule ();
2598+ if (CatchNode catchNode = ASTScope::lookupCatchNode (module , loc)) {
2599+ if (auto caughtType = catchNode.getThrownErrorTypeInContext (Ctx))
2600+ return *caughtType;
2601+ }
2602+
2603+ // Fall back to the error existential.
2604+ return Ctx.getErrorExistentialType ();
2605+ }
2606+
25902607public:
25912608 CheckEffectsCoverage (ASTContext &ctx, Context initialContext)
25922609 : Ctx(ctx), CurContext(initialContext),
@@ -2706,6 +2723,11 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
27062723 // specialized diagnostic about non-exhaustive catches.
27072724 if (!CurContext.handlesThrows (ConditionalEffectKind::Conditional)) {
27082725 CurContext.setNonExhaustiveCatch (true );
2726+ } else if (Type rethrownErrorType = S->getCaughtErrorType ()) {
2727+ // We're implicitly rethrowing the error out of this do..catch, so make
2728+ // sure that we can throw an error of this type out of this context.
2729+ auto catches = S->getCatches ();
2730+ checkThrownErrorType (catches.back ()->getEndLoc (), rethrownErrorType);
27092731 }
27102732
27112733 S->getBody ()->walk (*this );
@@ -2727,14 +2749,15 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
27272749 }
27282750
27292751 void checkCatch (CaseStmt *S, ConditionalEffectKind doThrowingKind) {
2752+ auto dc = CurContext.getDeclContext ();
27302753 for (auto &LabelItem : S->getMutableCaseLabelItems ()) {
27312754 // The pattern and guard aren't allowed to throw.
27322755 {
2733- ContextScope scope (*this , Context::forCatchPattern (S));
2756+ ContextScope scope (*this , Context::forCatchPattern (S, dc ));
27342757 LabelItem.getPattern ()->walk (*this );
27352758 }
27362759 if (auto guard = LabelItem.getGuardExpr ()) {
2737- ContextScope scope (*this , Context::forCatchGuard (S));
2760+ ContextScope scope (*this , Context::forCatchGuard (S, dc ));
27382761 guard->walk (*this );
27392762 }
27402763 }
@@ -2943,11 +2966,27 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
29432966 } else if (!isTryCovered) {
29442967 CurContext.diagnoseUncoveredThrowSite (Ctx, E, // we want this one to trigger
29452968 classification.getThrowReason ());
2969+ } else {
2970+ checkThrownErrorType (E.getStartLoc (), classification.getThrownError ());
29462971 }
29472972 break ;
29482973 }
29492974 }
29502975
2976+ // / Check the thrown error type against the type that can be caught or
2977+ // / rethrown by the context.
2978+ void checkThrownErrorType (SourceLoc loc, Type thrownErrorType) {
2979+ Type caughtErrorType = getCaughtErrorTypeAt (loc);
2980+ if (caughtErrorType->isEqual (thrownErrorType))
2981+ return ;
2982+
2983+ OpaqueValueExpr *opaque = new (Ctx) OpaqueValueExpr (loc, thrownErrorType);
2984+ Expr *rethrowExpr = opaque;
2985+ TypeChecker::typeCheckExpression (
2986+ rethrowExpr, CurContext.getDeclContext (),
2987+ {caughtErrorType, /* FIXME:*/ CTP_ThrowStmt});
2988+ }
2989+
29512990 ShouldRecurse_t checkAwait (AwaitExpr *E) {
29522991
29532992 // Walk the operand.
@@ -3206,7 +3245,7 @@ void TypeChecker::checkFunctionEffects(AbstractFunctionDecl *fn) {
32063245
32073246 auto isDeferBody = isa<FuncDecl>(fn) && cast<FuncDecl>(fn)->isDeferBody ();
32083247 auto context =
3209- isDeferBody ? Context::forDeferBody () : Context::forFunction (fn);
3248+ isDeferBody ? Context::forDeferBody (fn ) : Context::forFunction (fn);
32103249 auto &ctx = fn->getASTContext ();
32113250 CheckEffectsCoverage checker (ctx, context);
32123251
0 commit comments