@@ -1718,14 +1718,15 @@ class Context {
1718
1718
private:
1719
1719
static Context getContextForPatternBinding (PatternBindingDecl *pbd) {
1720
1720
if (!pbd->isStatic () && pbd->getDeclContext ()->isTypeContext ()) {
1721
- return Context (Kind::IVarInitializer);
1721
+ return Context (Kind::IVarInitializer, pbd-> getDeclContext () );
1722
1722
} else {
1723
- return Context (Kind::GlobalVarInitializer);
1723
+ return Context (Kind::GlobalVarInitializer, pbd-> getDeclContext () );
1724
1724
}
1725
1725
}
1726
1726
1727
1727
Kind TheKind;
1728
1728
llvm::Optional<AnyFunctionRef> Function;
1729
+ DeclContext *DC;
1729
1730
bool HandlesErrors = false ;
1730
1731
bool HandlesAsync = false ;
1731
1732
@@ -1736,14 +1737,15 @@ class Context {
1736
1737
bool DiagnoseErrorOnTry = false ;
1737
1738
InterpolatedStringLiteralExpr *InterpolatedString = nullptr ;
1738
1739
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 ) {
1741
1742
assert (TheKind != Kind::PotentiallyHandled);
1742
1743
}
1743
1744
1744
1745
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),
1747
1749
HandlesErrors(handlesErrors), HandlesAsync(handlesAsync) {}
1748
1750
1749
1751
public:
@@ -1820,7 +1822,7 @@ class Context {
1820
1822
static Context forTopLevelCode (TopLevelCodeDecl *D) {
1821
1823
// Top-level code implicitly handles errors.
1822
1824
return Context (/* handlesErrors=*/ true ,
1823
- /* handlesAsync=*/ D->isAsyncContext (), llvm::None);
1825
+ /* handlesAsync=*/ D->isAsyncContext (), llvm::None, D );
1824
1826
}
1825
1827
1826
1828
static Context forFunction (AbstractFunctionDecl *D) {
@@ -1840,20 +1842,20 @@ class Context {
1840
1842
}
1841
1843
}
1842
1844
1843
- return Context (D->hasThrows (), D->isAsyncContext (), AnyFunctionRef (D));
1845
+ return Context (D->hasThrows (), D->isAsyncContext (), AnyFunctionRef (D), D );
1844
1846
}
1845
1847
1846
- static Context forDeferBody () {
1847
- return Context (Kind::DeferBody);
1848
+ static Context forDeferBody (DeclContext *dc ) {
1849
+ return Context (Kind::DeferBody, dc );
1848
1850
}
1849
1851
1850
1852
static Context forInitializer (Initializer *init) {
1851
1853
if (isa<DefaultArgumentInitializer>(init)) {
1852
- return Context (Kind::DefaultArgument);
1854
+ return Context (Kind::DefaultArgument, init );
1853
1855
}
1854
1856
1855
1857
if (isa<PropertyWrapperInitializer>(init)) {
1856
- return Context (Kind::PropertyWrapper);
1858
+ return Context (Kind::PropertyWrapper, init );
1857
1859
}
1858
1860
1859
1861
auto *binding = cast<PatternBindingInitializer>(init)->getBinding ();
@@ -1863,7 +1865,7 @@ class Context {
1863
1865
}
1864
1866
1865
1867
static Context forEnumElementInitializer (EnumElementDecl *elt) {
1866
- return Context (Kind::EnumElementInitializer);
1868
+ return Context (Kind::EnumElementInitializer, elt );
1867
1869
}
1868
1870
1869
1871
static Context forClosure (AbstractClosureExpr *E) {
@@ -1877,15 +1879,15 @@ class Context {
1877
1879
}
1878
1880
}
1879
1881
1880
- return Context (closureTypeThrows, closureTypeIsAsync, AnyFunctionRef (E));
1882
+ return Context (closureTypeThrows, closureTypeIsAsync, AnyFunctionRef (E), E );
1881
1883
}
1882
1884
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 );
1885
1887
}
1886
1888
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 );
1889
1891
}
1890
1892
1891
1893
static Context forPatternBinding (PatternBindingDecl *binding) {
@@ -1909,6 +1911,8 @@ class Context {
1909
1911
1910
1912
Kind getKind () const { return TheKind; }
1911
1913
1914
+ DeclContext *getDeclContext () const { return DC; }
1915
+
1912
1916
bool handlesThrows (ConditionalEffectKind errorKind) const {
1913
1917
switch (errorKind) {
1914
1918
case ConditionalEffectKind::None:
@@ -2587,6 +2591,19 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2587
2591
}
2588
2592
};
2589
2593
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
+
2590
2607
public:
2591
2608
CheckEffectsCoverage (ASTContext &ctx, Context initialContext)
2592
2609
: Ctx(ctx), CurContext(initialContext),
@@ -2706,6 +2723,11 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2706
2723
// specialized diagnostic about non-exhaustive catches.
2707
2724
if (!CurContext.handlesThrows (ConditionalEffectKind::Conditional)) {
2708
2725
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);
2709
2731
}
2710
2732
2711
2733
S->getBody ()->walk (*this );
@@ -2727,14 +2749,15 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2727
2749
}
2728
2750
2729
2751
void checkCatch (CaseStmt *S, ConditionalEffectKind doThrowingKind) {
2752
+ auto dc = CurContext.getDeclContext ();
2730
2753
for (auto &LabelItem : S->getMutableCaseLabelItems ()) {
2731
2754
// The pattern and guard aren't allowed to throw.
2732
2755
{
2733
- ContextScope scope (*this , Context::forCatchPattern (S));
2756
+ ContextScope scope (*this , Context::forCatchPattern (S, dc ));
2734
2757
LabelItem.getPattern ()->walk (*this );
2735
2758
}
2736
2759
if (auto guard = LabelItem.getGuardExpr ()) {
2737
- ContextScope scope (*this , Context::forCatchGuard (S));
2760
+ ContextScope scope (*this , Context::forCatchGuard (S, dc ));
2738
2761
guard->walk (*this );
2739
2762
}
2740
2763
}
@@ -2943,11 +2966,27 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2943
2966
} else if (!isTryCovered) {
2944
2967
CurContext.diagnoseUncoveredThrowSite (Ctx, E, // we want this one to trigger
2945
2968
classification.getThrowReason ());
2969
+ } else {
2970
+ checkThrownErrorType (E.getStartLoc (), classification.getThrownError ());
2946
2971
}
2947
2972
break ;
2948
2973
}
2949
2974
}
2950
2975
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
+
2951
2990
ShouldRecurse_t checkAwait (AwaitExpr *E) {
2952
2991
2953
2992
// Walk the operand.
@@ -3206,7 +3245,7 @@ void TypeChecker::checkFunctionEffects(AbstractFunctionDecl *fn) {
3206
3245
3207
3246
auto isDeferBody = isa<FuncDecl>(fn) && cast<FuncDecl>(fn)->isDeferBody ();
3208
3247
auto context =
3209
- isDeferBody ? Context::forDeferBody () : Context::forFunction (fn);
3248
+ isDeferBody ? Context::forDeferBody (fn ) : Context::forFunction (fn);
3210
3249
auto &ctx = fn->getASTContext ();
3211
3250
CheckEffectsCoverage checker (ctx, context);
3212
3251
0 commit comments