Skip to content

Commit

Permalink
Merge pull request apple#34340 from slavapestov/fix-effect-check-cont…
Browse files Browse the repository at this point in the history
…ext-state

Sema: Fix failure to diagnose throwing expressions inside string interpolations
  • Loading branch information
slavapestov committed Oct 17, 2020
2 parents 907b069 + 5d6cf5c commit 2ae0c80
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/Sema/TypeCheckEffects.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -1375,6 +1382,7 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
DeclContext *OldRethrowsDC;
ContextFlags OldFlags;
ThrowingKind OldMaxThrowingKind;

public:
ContextScope(CheckEffectsCoverage &self, Optional<Context> newContext)
: Self(self), OldContext(self.CurContext),
Expand Down Expand Up @@ -1468,7 +1476,15 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
}

~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;
Expand Down
9 changes: 9 additions & 0 deletions test/expr/unary/async_await.swift
Expand Up @@ -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()
}
13 changes: 13 additions & 0 deletions test/stmt/errors.swift
Expand Up @@ -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())"
}

0 comments on commit 2ae0c80

Please sign in to comment.