Skip to content

Commit eb8c8ec

Browse files
authored
Merge pull request #35323 from slavapestov/effect-checker-missing-throws-fix-5.4
Sema: Fix preservation of DiagnoseErrorOnTry flag [5.4]
2 parents e81ed9f + 99269dd commit eb8c8ec

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,10 +1579,22 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
15791579
OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
15801580
}
15811581

1582+
void preserveDiagnoseErrorOnTryFlag() {
1583+
// The "DiagnoseErrorOnTry" flag is a bit of mutable state
1584+
// in the Context itself, used to postpone diagnostic emission
1585+
// to a parent "try" expression. If something was diagnosed
1586+
// during this ContextScope, the flag may have been set, and
1587+
// we need to preseve its value when restoring the old Context.
1588+
bool DiagnoseErrorOnTry = Self.CurContext.shouldDiagnoseErrorOnTry();
1589+
OldContext.setDiagnoseErrorOnTry(DiagnoseErrorOnTry);
1590+
}
1591+
15821592
void preserveCoverageFromAwaitOperand() {
15831593
OldFlags.mergeFrom(ContextFlags::HasAnyAwait, Self.Flags);
15841594
OldFlags.mergeFrom(ContextFlags::throwFlags(), Self.Flags);
15851595
OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
1596+
1597+
preserveDiagnoseErrorOnTryFlag();
15861598
}
15871599

15881600
void preserveCoverageFromTryOperand() {
@@ -1601,22 +1613,16 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
16011613
OldFlags.mergeFrom(ContextFlags::HasAnyAsyncSite, Self.Flags);
16021614
OldFlags.mergeFrom(ContextFlags::HasAnyAwait, Self.Flags);
16031615
OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
1616+
1617+
preserveDiagnoseErrorOnTryFlag();
16041618
}
16051619

16061620
bool wasTopLevelDebuggerFunction() const {
16071621
return OldFlags.has(ContextFlags::IsTopLevelDebuggerFunction);
16081622
}
16091623

16101624
~ContextScope() {
1611-
// The "DiagnoseErrorOnTry" flag is a bit of mutable state
1612-
// in the Context itself, used to postpone diagnostic emission
1613-
// to a parent "try" expression. If something was diagnosed
1614-
// during this ContextScope, the flag may have been set, and
1615-
// we need to preseve its value when restoring the old Context.
1616-
bool DiagnoseErrorOnTry = Self.CurContext.shouldDiagnoseErrorOnTry();
16171625
Self.CurContext = OldContext;
1618-
Self.CurContext.setDiagnoseErrorOnTry(DiagnoseErrorOnTry);
1619-
16201626
Self.RethrowsDC = OldRethrowsDC;
16211627
Self.Flags = OldFlags;
16221628
Self.MaxThrowingKind = OldMaxThrowingKind;

test/Concurrency/async_tasks.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func test_unsafeContinuations() async {
5353
}
5454
}
5555

56-
func test_unsafeThrowingContinuations() async {
56+
func test_unsafeThrowingContinuations() async throws {
5757
let _: String = await try withUnsafeThrowingContinuation { continuation in
5858
continuation.resume(returning: "")
5959
}

test/stmt/errors.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,11 @@ func sr_13654_invalid_interpolation() {
263263
func sr_13654_valid_interpolation() throws {
264264
_ = try "\(sr_13654_func())"
265265
_ = "\(try sr_13654_func())"
266+
}
267+
268+
// rdar://problem/72748150
269+
func takesClosure(_: (() -> ())) throws -> Int {}
270+
271+
func passesClosure() {
272+
_ = try takesClosure { } // expected-error {{errors thrown from here are not handled}}
266273
}

test/stmt/errors_async.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -typecheck -verify %s -enable-experimental-concurrency
2+
3+
// REQUIRES: concurrency
4+
5+
enum MyError : Error {
6+
case bad
7+
}
8+
9+
func shouldThrow() async {
10+
// expected-error@+1 {{errors thrown from here are not handled}}
11+
let _: Int = await try withUnsafeThrowingContinuation { continuation in
12+
continuation.resume(throwing: MyError.bad)
13+
}
14+
}

0 commit comments

Comments
 (0)