Skip to content

Commit b386d5d

Browse files
[Sema] Adapt ApplyClassifier to be able to classify SelfApplyExpr in some contexts
1 parent 0005c1f commit b386d5d

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,12 @@ 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+
727733
DeclContext *getPolymorphicEffectDeclContext(EffectKind kind) const {
728734
switch (kind) {
729735
case EffectKind::Throws: return RethrowsDC;
@@ -745,16 +751,29 @@ class ApplyClassifier {
745751

746752
/// Check to see if the given function application throws or is async.
747753
Classification classifyApply(ApplyExpr *E) {
748-
if (isa<SelfApplyExpr>(E)) {
749-
assert(!E->isImplicitlyAsync());
750-
return Classification();
751-
}
752-
753754
// An apply expression is a potential throw site if the function throws.
754755
// But if the expression didn't type-check, suppress diagnostics.
755756
if (!E->getType() || E->getType()->hasError())
756757
return Classification::forInvalidCode();
757758

759+
if (auto *SAE = dyn_cast<SelfApplyExpr>(E)) {
760+
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();
775+
}
776+
758777
auto type = E->getFn()->getType();
759778
if (!type) return Classification::forInvalidCode();
760779
auto fnType = type->getAs<AnyFunctionType>();
@@ -2957,6 +2976,8 @@ void TypeChecker::checkPropertyWrapperEffects(
29572976
}
29582977

29592978
bool TypeChecker::canThrow(Expr *expr) {
2960-
return (ApplyClassifier().classifyExpr(expr, EffectKind::Throws)
2961-
== ConditionalEffectKind::Always);
2979+
ApplyClassifier classifier;
2980+
classifier.ClassifySelfApplyExpr = true;
2981+
return (classifier.classifyExpr(expr, EffectKind::Throws) ==
2982+
ConditionalEffectKind::Always);
29622983
}

0 commit comments

Comments
 (0)