Skip to content

Commit a8f60a5

Browse files
committed
Rely on the next/nextElement call in an async for..each for throws effects
Our decision procedure for what type of error is thrown during iteration of an async sequence was effectively duplicated between the checking for the next/nextElement call (which is synthesized) and separate logic for the async for..in loop. The latter is strictly redundant, so switch to relying only on the former. This is staging for customizing the next/nextElement call further.
1 parent ec945bf commit a8f60a5

File tree

2 files changed

+9
-15
lines changed

2 files changed

+9
-15
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,13 +1468,11 @@ class ApplyClassifier {
14681468
ConditionalEffectKind::Always,
14691469
PotentialEffectReason::forApply());
14701470

1471-
// Use the conformance to AsyncSequence to determine whether (and what)
1472-
// is thrown.
1473-
auto conformance = stmt->getSequenceConformance();
1474-
Type sequenceType = stmt->getSequenceType();
1475-
result.merge(
1476-
classifyConformance(
1477-
sequenceType, conformance, EffectKind::Throws));
1471+
if (!stmt->getNextCall())
1472+
return Classification::forInvalidCode();
1473+
1474+
// Merge the thrown result from the next/nextElement call.
1475+
result.merge(classifyExpr(stmt->getNextCall(), EffectKind::Throws));
14781476

14791477
return result;
14801478
}
@@ -3501,11 +3499,9 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
35013499
if (throwsKind != ConditionalEffectKind::None)
35023500
Flags.set(ContextFlags::HasAnyThrowSite);
35033501

3504-
if (!CurContext.handlesThrows(throwsKind))
3505-
CurContext.diagnoseUnhandledThrowStmt(Ctx.Diags, S);
3506-
3507-
// Note: we don't need to check the thrown error type specifically,
3508-
// because we will also be checking the nextElement call.
3502+
// Note: we don't need to check whether the throw error is handled,
3503+
// because we will also be checking the generated next/nextElement
3504+
// call.
35093505
}
35103506

35113507
return ShouldRecurse;

test/Concurrency/async_sequence_syntax.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ func missingAsync<T : AsyncSequence>(_ seq: T) throws {
1515
@available(SwiftStdlib 5.1, *)
1616
func missingThrows<T : AsyncSequence>(_ seq: T) async {
1717
for try await _ in seq { }
18-
// expected-error@-1 {{error is not handled because the enclosing function is not declared 'throws'}}
19-
// expected-error@-2 {{errors thrown from here are not handled}}
18+
// expected-error@-1 {{errors thrown from here are not handled}}
2019
}
2120

2221
@available(SwiftStdlib 5.1, *)
@@ -37,7 +36,6 @@ func missingTryInBlock<T : AsyncSequence>(_ seq: T) {
3736
for await _ in seq { }
3837
// expected-error@-1{{call can throw, but the error is not handled}}
3938
// expected-error@-2{{errors thrown from here are not handled}}
40-
// expected-error@-3{{error is not handled because the enclosing function is not declared 'throws'}}
4139
}
4240
}
4341

0 commit comments

Comments
 (0)