Skip to content

Commit f601a6c

Browse files
authored
Merge pull request swiftlang#35321 from slavapestov/effect-checker-missing-throws-fix
Sema: Fix preservation of DiagnoseErrorOnTry flag
2 parents 953b30b + c54f19c commit f601a6c

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
@@ -1584,10 +1584,22 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
15841584
OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
15851585
}
15861586

1587+
void preserveDiagnoseErrorOnTryFlag() {
1588+
// The "DiagnoseErrorOnTry" flag is a bit of mutable state
1589+
// in the Context itself, used to postpone diagnostic emission
1590+
// to a parent "try" expression. If something was diagnosed
1591+
// during this ContextScope, the flag may have been set, and
1592+
// we need to preseve its value when restoring the old Context.
1593+
bool DiagnoseErrorOnTry = Self.CurContext.shouldDiagnoseErrorOnTry();
1594+
OldContext.setDiagnoseErrorOnTry(DiagnoseErrorOnTry);
1595+
}
1596+
15871597
void preserveCoverageFromAwaitOperand() {
15881598
OldFlags.mergeFrom(ContextFlags::HasAnyAwait, Self.Flags);
15891599
OldFlags.mergeFrom(ContextFlags::throwFlags(), Self.Flags);
15901600
OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
1601+
1602+
preserveDiagnoseErrorOnTryFlag();
15911603
}
15921604

15931605
void preserveCoverageFromTryOperand() {
@@ -1606,22 +1618,16 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
16061618
OldFlags.mergeFrom(ContextFlags::HasAnyAsyncSite, Self.Flags);
16071619
OldFlags.mergeFrom(ContextFlags::HasAnyAwait, Self.Flags);
16081620
OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
1621+
1622+
preserveDiagnoseErrorOnTryFlag();
16091623
}
16101624

16111625
bool wasTopLevelDebuggerFunction() const {
16121626
return OldFlags.has(ContextFlags::IsTopLevelDebuggerFunction);
16131627
}
16141628

16151629
~ContextScope() {
1616-
// The "DiagnoseErrorOnTry" flag is a bit of mutable state
1617-
// in the Context itself, used to postpone diagnostic emission
1618-
// to a parent "try" expression. If something was diagnosed
1619-
// during this ContextScope, the flag may have been set, and
1620-
// we need to preseve its value when restoring the old Context.
1621-
bool DiagnoseErrorOnTry = Self.CurContext.shouldDiagnoseErrorOnTry();
16221630
Self.CurContext = OldContext;
1623-
Self.CurContext.setDiagnoseErrorOnTry(DiagnoseErrorOnTry);
1624-
16251631
Self.RethrowsDC = OldRethrowsDC;
16261632
Self.Flags = OldFlags;
16271633
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 = try await 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 = try await withUnsafeThrowingContinuation { continuation in
12+
continuation.resume(throwing: MyError.bad)
13+
}
14+
}

0 commit comments

Comments
 (0)