Skip to content

Commit bd8ebcf

Browse files
Merge pull request swiftlang#60148 from LucianoPAlmeida/revert-apply-classifier
[Sema] Don't early exit without looking at conformances in ApplyClassifier
2 parents 2936334 + ec2b841 commit bd8ebcf

File tree

2 files changed

+23
-26
lines changed

2 files changed

+23
-26
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -724,12 +724,6 @@ class ApplyClassifier {
724724
DeclContext *RethrowsDC = nullptr;
725725
DeclContext *ReasyncDC = nullptr;
726726

727-
// Indicates if `classifyApply` will attempt to classify SelfApplyExpr
728-
// because that should be done only in certain contexts like when infering
729-
// if "async let" implicit auto closure wrapping initialize expression can
730-
// throw.
731-
bool ClassifySelfApplyExpr = false;
732-
733727
DeclContext *getPolymorphicEffectDeclContext(EffectKind kind) const {
734728
switch (kind) {
735729
case EffectKind::Throws: return RethrowsDC;
@@ -758,38 +752,29 @@ class ApplyClassifier {
758752

759753
if (auto *SAE = dyn_cast<SelfApplyExpr>(E)) {
760754
assert(!E->isImplicitlyAsync());
761-
762-
if (ClassifySelfApplyExpr) {
763-
// Do not consider throw properties in SelfAssignExpr with an implicit
764-
// conversion base.
765-
if (isa<ImplicitConversionExpr>(SAE->getBase()))
766-
return Classification();
767-
768-
auto fnType = E->getType()->getAs<AnyFunctionType>();
769-
if (fnType && fnType->isThrowing()) {
770-
return Classification::forUnconditional(
771-
EffectKind::Throws, PotentialEffectReason::forApply());
772-
}
773-
}
774-
return Classification();
775755
}
776756

777757
auto type = E->getFn()->getType();
778758
if (!type) return Classification::forInvalidCode();
779759
auto fnType = type->getAs<AnyFunctionType>();
780760
if (!fnType) return Classification::forInvalidCode();
781761

782-
// If the function doesn't have any effects, we're done here.
762+
auto fnRef = AbstractFunction::getAppliedFn(E);
763+
auto conformances = fnRef.getSubstitutions().getConformances();
764+
const auto hasAnyConformances = !conformances.empty();
765+
766+
// If the function doesn't have any effects or conformances, we're done
767+
// here.
783768
if (!fnType->isThrowing() &&
784769
!E->implicitlyThrows() &&
785770
!fnType->isAsync() &&
786-
!E->isImplicitlyAsync()) {
771+
!E->isImplicitlyAsync() &&
772+
!hasAnyConformances) {
787773
return Classification();
788774
}
789775

790776
// Decompose the application.
791777
auto *args = E->getArgs();
792-
auto fnRef = AbstractFunction::getAppliedFn(E);
793778

794779
// If any of the arguments didn't type check, fail.
795780
for (auto arg : *args) {
@@ -2983,7 +2968,6 @@ void TypeChecker::checkPropertyWrapperEffects(
29832968

29842969
bool TypeChecker::canThrow(Expr *expr) {
29852970
ApplyClassifier classifier;
2986-
classifier.ClassifySelfApplyExpr = true;
2987-
return (classifier.classifyExpr(expr, EffectKind::Throws) ==
2988-
ConditionalEffectKind::Always);
2971+
auto effect = classifier.classifyExpr(expr, EffectKind::Throws);
2972+
return (effect != ConditionalEffectKind::None);
29892973
}

test/Concurrency/sr15049.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,16 @@ func testAsyncSequence3<Seq>(_ seq: Seq) async throws where Seq: AsyncSequence,
4949
func testAsyncSequence4<Seq>(_ seq: Seq) async throws where Seq: AsyncSequence, Seq.Element == Int { // expected-note{{consider making generic parameter 'Seq' conform to the 'Sendable' protocol}} {{28-28=: Sendable}}
5050
async let _ = seq // expected-warning{{capture of 'seq' with non-sendable type 'Seq' in 'async let' binding}}
5151
}
52+
53+
func search(query: String, entities: [String]) async throws -> [String] {
54+
async let r = entities.filter { $0.contains(query) }.map { String($0) }
55+
return await r // OK
56+
}
57+
58+
// https://github.com/apple/swift/issues/60351
59+
func foo() async {
60+
let stream = AsyncStream<Int>{ _ in }
61+
async let bar = stream.first { _ in true}
62+
63+
_ = await bar // OK
64+
}

0 commit comments

Comments
 (0)