Skip to content

Commit 4553515

Browse files
authored
Merge pull request #68801 from hamishknight/try-try-again-5.10
2 parents 26f3dbd + d20a3b0 commit 4553515

File tree

5 files changed

+1020
-0
lines changed

5 files changed

+1020
-0
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,8 @@ class EffectsHandlingWalker : public ASTWalker {
448448
recurse = asImpl().checkInterpolatedStringLiteral(interpolated);
449449
} else if (auto macroExpansionExpr = dyn_cast<MacroExpansionExpr>(E)) {
450450
recurse = ShouldRecurse;
451+
} else if (auto *SVE = dyn_cast<SingleValueStmtExpr>(E)) {
452+
recurse = asImpl().checkSingleValueStmtExpr(SVE);
451453
}
452454
// Error handling validation (via checkTopLevelEffects) happens after
453455
// type checking. If an unchecked expression is still around, the code was
@@ -1076,6 +1078,10 @@ class ApplyClassifier {
10761078
return ShouldRecurse;
10771079
}
10781080

1081+
ShouldRecurse_t checkSingleValueStmtExpr(SingleValueStmtExpr *SVE) {
1082+
return ShouldRecurse;
1083+
}
1084+
10791085
ConditionalEffectKind checkExhaustiveDoBody(DoCatchStmt *S) {
10801086
// All errors thrown by the do body are caught, but any errors thrown
10811087
// by the catch bodies are bounded by the throwing kind of the do body.
@@ -1196,6 +1202,10 @@ class ApplyClassifier {
11961202
return ShouldRecurse;
11971203
}
11981204

1205+
ShouldRecurse_t checkSingleValueStmtExpr(SingleValueStmtExpr *SVE) {
1206+
return ShouldRecurse;
1207+
}
1208+
11991209
void visitExprPre(Expr *expr) { return; }
12001210
};
12011211

@@ -2211,6 +2221,15 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
22112221
// 'async'.
22122222
}
22132223

2224+
void preserveCoverageFromSingleValueStmtExpr() {
2225+
// We need to preserve whether we saw any throwing sites, to avoid warning
2226+
// on 'do { let x = if .random() { try ... } else { ... } } catch { ... }'
2227+
OldFlags.mergeFrom(ContextFlags::HasAnyThrowSite, Self.Flags);
2228+
2229+
// We need to preserve the throwing kind to correctly handle rethrows.
2230+
OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
2231+
}
2232+
22142233
void preserveCoverageFromNonExhaustiveCatch() {
22152234
OldFlags.mergeFrom(ContextFlags::HasAnyThrowSite, Self.Flags);
22162235
OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
@@ -2354,6 +2373,17 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
23542373
return ShouldNotRecurse;
23552374
}
23562375

2376+
ShouldRecurse_t
2377+
checkSingleValueStmtExpr(SingleValueStmtExpr *SVE) {
2378+
// For an if/switch expression, we reset coverage such that a 'try'/'await'
2379+
// does not cover the branches.
2380+
ContextScope scope(*this, /*newContext*/ llvm::None);
2381+
scope.resetCoverage();
2382+
SVE->getStmt()->walk(*this);
2383+
scope.preserveCoverageFromSingleValueStmtExpr();
2384+
return ShouldNotRecurse;
2385+
}
2386+
23572387
ConditionalEffectKind checkExhaustiveDoBody(DoCatchStmt *S) {
23582388
// This is a context where errors are handled.
23592389
ContextScope scope(*this, CurContext.withHandlesErrors());

0 commit comments

Comments
 (0)