Skip to content

Commit dcfeff7

Browse files
authored
Merge pull request #61944 from angela-laar/refactor-generate-constraints-for-closures
[CSClosure] Refactor generateConstraints
2 parents b89ab84 + b6637e4 commit dcfeff7

File tree

3 files changed

+40
-45
lines changed

3 files changed

+40
-45
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5042,15 +5042,7 @@ class ConstraintSystem {
50425042
bool generateConstraints(SolutionApplicationTarget &target,
50435043
FreeTypeVariableBinding allowFreeTypeVariables);
50445044

5045-
/// Generate constraints for the body of the given closure.
5046-
///
5047-
/// \param closure the closure expression
5048-
///
5049-
/// \returns \c true if constraint generation failed, \c false otherwise
5050-
LLVM_NODISCARD
5051-
bool generateConstraints(ClosureExpr *closure);
5052-
5053-
/// Generate constraints for the body of the given function.
5045+
/// Generate constraints for the body of the given function or closure.
50545046
///
50555047
/// \param fn The function or closure expression
50565048
/// \param body The body of the given function that should be

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10798,7 +10798,7 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
1079810798
setSolutionApplicationTarget(closure, target);
1079910799

1080010800
// Generate constraints from the body of this closure.
10801-
return !generateConstraints(closure);
10801+
return !generateConstraints(AnyFunctionRef{closure}, closure->getBody());
1080210802
}
1080310803

1080410804
ConstraintSystem::SolutionKind
@@ -14545,7 +14545,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1454514545

1454614546
case ConstraintKind::Disjunction:
1454714547
case ConstraintKind::Conjunction:
14548-
// {Dis, Con}junction constraints are never solved here.
14548+
// See {Dis, Con}junctionStep class in CSStep.cpp for solving
1454914549
return SolutionKind::Unsolved;
1455014550

1455114551
case ConstraintKind::OneWayEqual:

lib/Sema/CSSyntacticElement.cpp

Lines changed: 37 additions & 34 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
}
@@ -905,6 +910,8 @@ class SyntacticElementConstraintGenerator
905910
}
906911

907912
void visitBraceStmt(BraceStmt *braceStmt) {
913+
auto &ctx = cs.getASTContext();
914+
908915
if (context.isSingleExpressionClosure(cs)) {
909916
for (auto node : braceStmt->getElements()) {
910917
if (auto expr = node.dyn_cast<Expr *>()) {
@@ -922,7 +929,36 @@ class SyntacticElementConstraintGenerator
922929
return;
923930
}
924931

925-
auto &ctx = cs.getASTContext();
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+
}
926962

927963
if (isChildOf(StmtKind::Case)) {
928964
auto *caseStmt = cast<CaseStmt>(
@@ -1122,39 +1158,6 @@ class SyntacticElementConstraintGenerator
11221158
};
11231159
}
11241160

1125-
bool ConstraintSystem::generateConstraints(ClosureExpr *closure) {
1126-
auto &ctx = closure->getASTContext();
1127-
1128-
if (participatesInInference(closure)) {
1129-
SyntacticElementConstraintGenerator generator(
1130-
*this, SyntacticElementContext::forClosure(closure),
1131-
getConstraintLocator(closure));
1132-
1133-
generator.visit(closure->getBody());
1134-
1135-
if (closure->hasSingleExpressionBody())
1136-
return generator.hadError;
1137-
}
1138-
1139-
// If this closure has an empty body and no explicit result type
1140-
// let's bind result type to `Void` since that's the only type empty body
1141-
// can produce. Otherwise, if (multi-statement) closure doesn't have
1142-
// an explicit result (no `return` statements) let's default it to `Void`.
1143-
if (!hasExplicitResult(closure)) {
1144-
auto constraintKind =
1145-
(closure->hasEmptyBody() && !closure->hasExplicitResultType())
1146-
? ConstraintKind::Bind
1147-
: ConstraintKind::Defaultable;
1148-
1149-
addConstraint(
1150-
constraintKind, getClosureType(closure)->getResult(),
1151-
ctx.TheEmptyTupleType,
1152-
getConstraintLocator(closure, ConstraintLocator::ClosureResult));
1153-
}
1154-
1155-
return false;
1156-
}
1157-
11581161
bool ConstraintSystem::generateConstraints(AnyFunctionRef fn, BraceStmt *body) {
11591162
NullablePtr<ConstraintLocator> locator;
11601163

0 commit comments

Comments
 (0)