Skip to content

Commit b6637e4

Browse files
committed
[CSSyntacticElement] Only add constraints when brace statement represents the whole body
1 parent 45fb989 commit b6637e4

File tree

1 file changed

+36
-38
lines changed

1 file changed

+36
-38
lines changed

lib/Sema/CSSyntacticElement.cpp

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,11 @@ struct SyntacticElementContext
383383
}
384384
}
385385

386+
NullablePtr<ClosureExpr> getAsClosureExpr() const {
387+
return dyn_cast_or_null<ClosureExpr>(
388+
this->dyn_cast<AbstractClosureExpr *>());
389+
}
390+
386391
NullablePtr<AbstractClosureExpr> getAsAbstractClosureExpr() const {
387392
return this->dyn_cast<AbstractClosureExpr *>();
388393
}
@@ -907,36 +912,6 @@ class SyntacticElementConstraintGenerator
907912
void visitBraceStmt(BraceStmt *braceStmt) {
908913
auto &ctx = cs.getASTContext();
909914

910-
auto addResultDefault = [&](ClosureExpr *closure) {
911-
if (context.getBody() == braceStmt) {
912-
// If this closure has an empty body and no explicit result type
913-
// let's bind result type to `Void` since that's the only type empty
914-
// body can produce. Otherwise, if (multi-statement) closure doesn't
915-
// have an explicit result (no `return` statements) let's default it to
916-
// `Void`.
917-
if (!constraints::hasExplicitResult(closure)) {
918-
auto constraintKind =
919-
(closure->hasEmptyBody() && !closure->hasExplicitResultType())
920-
? ConstraintKind::Bind
921-
: ConstraintKind::Defaultable;
922-
923-
cs.addConstraint(constraintKind,
924-
cs.getClosureType(closure)->getResult(),
925-
ctx.TheEmptyTupleType,
926-
cs.getConstraintLocator(
927-
closure, ConstraintLocator::ClosureResult));
928-
}
929-
}
930-
};
931-
932-
if (auto closure = cast<ClosureExpr>(
933-
context.getAsAbstractClosureExpr().getPtrOrNull())) {
934-
if (!cs.participatesInInference(closure)) {
935-
addResultDefault(closure);
936-
return;
937-
}
938-
}
939-
940915
if (context.isSingleExpressionClosure(cs)) {
941916
for (auto node : braceStmt->getElements()) {
942917
if (auto expr = node.dyn_cast<Expr *>()) {
@@ -951,13 +926,40 @@ class SyntacticElementConstraintGenerator
951926
visitDecl(node.get<Decl *>());
952927
}
953928
}
954-
if (!hadError)
955-
addResultDefault(cast<ClosureExpr>(
956-
context.getAsAbstractClosureExpr().getPtrOrNull()));
957-
958929
return;
959930
}
960931

932+
// If this brace statement represents a body of an empty or
933+
// multi-statement closure.
934+
if (locator->directlyAt<ClosureExpr>()) {
935+
auto *closure = context.getAsClosureExpr().get();
936+
// If this closure has an empty body and no explicit result type
937+
// let's bind result type to `Void` since that's the only type empty
938+
// body can produce. Otherwise, if (multi-statement) closure doesn't
939+
// have an explicit result (no `return` statements) let's default it to
940+
// `Void`.
941+
//
942+
// Note that result builder bodies always have a `return` statement
943+
// at the end, so they don't need to be defaulted.
944+
if (!cs.getAppliedResultBuilderTransform({closure}) &&
945+
!hasExplicitResult(closure)) {
946+
auto constraintKind =
947+
(closure->hasEmptyBody() && !closure->hasExplicitResultType())
948+
? ConstraintKind::Bind
949+
: ConstraintKind::Defaultable;
950+
951+
cs.addConstraint(
952+
constraintKind, cs.getClosureType(closure)->getResult(),
953+
ctx.TheEmptyTupleType,
954+
cs.getConstraintLocator(closure, ConstraintLocator::ClosureResult));
955+
}
956+
957+
// Let's not walk into the body if empty or multi-statement closure
958+
// doesn't participate in inference.
959+
if (!cs.participatesInInference(closure))
960+
return;
961+
}
962+
961963
if (isChildOf(StmtKind::Case)) {
962964
auto *caseStmt = cast<CaseStmt>(
963965
locator->castLastElementTo<LocatorPathElt::SyntacticElement>()
@@ -988,10 +990,6 @@ class SyntacticElementConstraintGenerator
988990
/*contextualInfo=*/{}, isDiscarded));
989991
}
990992

991-
if (!hadError)
992-
addResultDefault(
993-
cast<ClosureExpr>(context.getAsAbstractClosureExpr().getPtrOrNull()));
994-
995993
createConjunction(cs, elements, locator);
996994
}
997995

0 commit comments

Comments
 (0)