diff --git a/lib/Sema/TypeCheckEffects.cpp b/lib/Sema/TypeCheckEffects.cpp index a21c6ba1d2146..1e9a54ee2b872 100644 --- a/lib/Sema/TypeCheckEffects.cpp +++ b/lib/Sema/TypeCheckEffects.cpp @@ -878,6 +878,13 @@ class Context { HandlesErrors(handlesErrors), HandlesAsync(handlesAsync) { } public: + bool shouldDiagnoseErrorOnTry() const { + return DiagnoseErrorOnTry; + } + void setDiagnoseErrorOnTry(bool b) { + DiagnoseErrorOnTry = b; + } + /// Whether this is a function that rethrows. bool isRethrows() const { if (!HandlesErrors) @@ -1375,6 +1382,7 @@ class CheckEffectsCoverage : public EffectsHandlingWalker DeclContext *OldRethrowsDC; ContextFlags OldFlags; ThrowingKind OldMaxThrowingKind; + public: ContextScope(CheckEffectsCoverage &self, Optional newContext) : Self(self), OldContext(self.CurContext), @@ -1468,7 +1476,15 @@ class CheckEffectsCoverage : public EffectsHandlingWalker } ~ContextScope() { + // The "DiagnoseErrorOnTry" flag is a bit of mutable state + // in the Context itself, used to postpone diagnostic emission + // to a parent "try" expression. If something was diagnosed + // during this ContextScope, the flag may have been set, and + // we need to preseve its value when restoring the old Context. + bool DiagnoseErrorOnTry = Self.CurContext.shouldDiagnoseErrorOnTry(); Self.CurContext = OldContext; + Self.CurContext.setDiagnoseErrorOnTry(DiagnoseErrorOnTry); + Self.RethrowsDC = OldRethrowsDC; Self.Flags = OldFlags; Self.MaxThrowingKind = OldMaxThrowingKind; diff --git a/test/expr/unary/async_await.swift b/test/expr/unary/async_await.swift index 3dc31a35ab1c9..be9fcee0e1dad 100644 --- a/test/expr/unary/async_await.swift +++ b/test/expr/unary/async_await.swift @@ -133,3 +133,12 @@ func testStringInterpolation() async throws { _ = "Eventually produces \(await getInt())" _ = await "Eventually produces \(getInt())" } + +// Make sure try await works too +func invalidAsyncFunction() async { + _ = try await throwingAndAsync() // expected-error {{errors thrown from here are not handled}} +} + +func validAsyncFunction() async throws { + _ = try await throwingAndAsync() +} \ No newline at end of file diff --git a/test/stmt/errors.swift b/test/stmt/errors.swift index a8760bd1a64c3..c5db7c72500a5 100644 --- a/test/stmt/errors.swift +++ b/test/stmt/errors.swift @@ -251,3 +251,16 @@ func sr_11402_func2(_ x: SR_11402_P) { print(y) } } + +// https://bugs.swift.org/browse/SR-13654 + +func sr_13654_func() throws -> String {} + +func sr_13654_invalid_interpolation() { + _ = try "\(sr_13654_func())" // expected-error {{errors thrown from here are not handled}} + _ = "\(try sr_13654_func())" // expected-error {{errors thrown from here are not handled}} +} +func sr_13654_valid_interpolation() throws { + _ = try "\(sr_13654_func())" + _ = "\(try sr_13654_func())" +} \ No newline at end of file