[CSClosure] Generate constraints for empty closure body

We should do this in the ConstraintGenerator instead of in a ConstraintSystem method.
This commit is contained in:
Angela Laar
2022-11-10 15:27:52 -08:00
parent b4549d63f0
commit 8257cc1e10
2 changed files with 22 additions and 22 deletions

View File

@@ -905,6 +905,27 @@ private:
}
void visitBraceStmt(BraceStmt *braceStmt) {
auto &ctx = cs.getASTContext();
if (auto closure = cast<ClosureExpr>(context.getAbstractClosureExpr());
context.getBody() == braceStmt) {
// If this closure has an empty body and no explicit result type
// let's bind result type to `Void` since that's the only type empty body
// can produce. Otherwise, if (multi-statement) closure doesn't have
// an explicit result (no `return` statements) let's default it to `Void`.
if (!constraints::hasExplicitResult(closure)) {
auto constraintKind =
(closure->hasEmptyBody() && !closure->hasExplicitResultType())
? ConstraintKind::Bind
: ConstraintKind::Defaultable;
cs.addConstraint(
constraintKind, cs.getClosureType(closure)->getResult(),
ctx.TheEmptyTupleType,
cs.getConstraintLocator(closure, ConstraintLocator::ClosureResult));
}
}
if (context.isSingleExpressionClosure(cs)) {
for (auto node : braceStmt->getElements()) {
if (auto expr = node.dyn_cast<Expr *>()) {
@@ -922,8 +943,6 @@ private:
return;
}
auto &ctx = cs.getASTContext();
if (isChildOf(StmtKind::Case)) {
auto *caseStmt = cast<CaseStmt>(
locator->castLastElementTo<LocatorPathElt::SyntacticElement>()
@@ -1131,8 +1150,6 @@ bool ConstraintSystem::generateConstraints(AnyFunctionRef fn, BraceStmt *body) {
auto closure = cast<ClosureExpr>(fn.getAbstractClosureExpr());
locator = getConstraintLocator(closure);
auto &ctx = closure->getASTContext();
if (participatesInInference(closure)) {
SyntacticElementConstraintGenerator generator(
*this, closure, getConstraintLocator(closure));
@@ -1143,22 +1160,6 @@ bool ConstraintSystem::generateConstraints(AnyFunctionRef fn, BraceStmt *body) {
return generator.hadError;
}
// If this closure has an empty body and no explicit result type
// let's bind result type to `Void` since that's the only type empty body
// can produce. Otherwise, if (multi-statement) closure doesn't have
// an explicit result (no `return` statements) let's default it to `Void`.
if (!hasExplicitResult(closure)) {
auto constraintKind =
(closure->hasEmptyBody() && !closure->hasExplicitResultType())
? ConstraintKind::Bind
: ConstraintKind::Defaultable;
addConstraint(
constraintKind, getClosureType(closure)->getResult(),
ctx.TheEmptyTupleType,
getConstraintLocator(closure, ConstraintLocator::ClosureResult));
}
return false;
}