Skip to content

Commit 75dcd34

Browse files
authored
Merge pull request swiftlang#36761 from slavapestov/for-await-concrete-conformance-fix
Sema: Fix effects checking of 'for await' with a concrete conformance
2 parents fbe2ca9 + d6db99a commit 75dcd34

File tree

2 files changed

+17
-16
lines changed

2 files changed

+17
-16
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,12 +1173,7 @@ class ApplyClassifier {
11731173

11741174
ShouldRecurse_t checkForEach(ForEachStmt *S) {
11751175
if (S->getAwaitLoc().isValid()) {
1176-
auto classification = Self.classifyConformance(
1177-
S->getSequenceConformance(),
1178-
EffectKind::Async);
1179-
IsInvalid |= classification.isInvalid();
1180-
AsyncKind = std::max(AsyncKind,
1181-
classification.getConditionalKind(EffectKind::Async));
1176+
AsyncKind = std::max(AsyncKind, ConditionalEffectKind::Always);
11821177
}
11831178

11841179
return ShouldRecurse;
@@ -2735,10 +2730,19 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
27352730
if (!S->getAwaitLoc().isValid())
27362731
return ShouldRecurse;
27372732

2733+
// A 'for await' is always async. There's no effect polymorphism
2734+
// via the conformance in a 'reasync' function body.
2735+
Flags.set(ContextFlags::HasAnyAsyncSite);
2736+
2737+
if (!CurContext.handlesAsync(ConditionalEffectKind::Always))
2738+
CurContext.diagnoseUnhandledAsyncSite(Ctx.Diags, S, None);
2739+
27382740
ApplyClassifier classifier;
27392741
classifier.RethrowsDC = RethrowsDC;
27402742
classifier.ReasyncDC = ReasyncDC;
27412743

2744+
// A 'for try await' might be effect polymorphic via the conformance
2745+
// in a 'rethrows' function body.
27422746
if (S->getTryLoc().isValid()) {
27432747
auto classification = classifier.classifyConformance(
27442748
S->getSequenceConformance(), EffectKind::Throws);
@@ -2751,16 +2755,6 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
27512755
CurContext.diagnoseUnhandledThrowStmt(Ctx.Diags, S);
27522756
}
27532757

2754-
auto classification = classifier.classifyConformance(
2755-
S->getSequenceConformance(), EffectKind::Async);
2756-
auto asyncKind = classification.getConditionalKind(EffectKind::Async);
2757-
2758-
if (asyncKind != ConditionalEffectKind::None)
2759-
Flags.set(ContextFlags::HasAnyAsyncSite);
2760-
2761-
if (!CurContext.handlesAsync(asyncKind))
2762-
CurContext.diagnoseUnhandledAsyncSite(Ctx.Diags, S, None);
2763-
27642758
return ShouldRecurse;
27652759
}
27662760
};

test/Concurrency/async_sequence_syntax.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,10 @@ func forAwaitInsideDoCatch<Source: AsyncSequence>(_ source: Source) async {
7575
}
7676
} catch {} // no-warning
7777
}
78+
79+
@available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
80+
func forAwaitWithConcreteType(_ seq: ThrowingAsyncSequence) throws { // expected-note {{add 'async' to function 'forAwaitWithConcreteType' to make it asynchronous}}
81+
for try await elt in seq { // expected-error {{'async' in a function that does not support concurrency}}
82+
_ = elt
83+
}
84+
}

0 commit comments

Comments
 (0)