Skip to content

Commit cc8db01

Browse files
authored
Merge pull request #30045 from DougGregor/function-builders-if-let
[Constraint system] Support if let / if case in function builders.
2 parents 1100144 + 4830c48 commit cc8db01

File tree

7 files changed

+222
-182
lines changed

7 files changed

+222
-182
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,13 @@ class BuilderClosureVisitor
259259

260260
// Generate constraints for the initialization.
261261
auto target = SolutionApplicationTarget::forInitialization(
262-
patternBinding->getInit(index), dc, patternType, pattern);
262+
patternBinding->getInit(index), dc, patternType, pattern,
263+
/*bindPatternVarsOneWay=*/true);
263264
if (cs->generateConstraints(target, FreeTypeVariableBinding::Disallow))
264265
continue;
265266

266267
// Keep track of this binding entry.
267268
applied.patternBindingEntries.insert({{patternBinding, index}, target});
268-
269-
// Bind the variables that occur in the pattern to the corresponding
270-
// type entry for the pattern itself.
271-
cs->bindVariablesInPattern(
272-
pattern, cs->getConstraintLocator(target.getAsExpr()));
273269
}
274270
}
275271

@@ -380,10 +376,6 @@ class BuilderClosureVisitor
380376
static bool isBuildableIfChainRecursive(IfStmt *ifStmt,
381377
unsigned &numPayloads,
382378
bool &isOptional) {
383-
// Check whether we can handle the conditional.
384-
if (!ConstraintSystem::canGenerateConstraints(ifStmt->getCond()))
385-
return false;
386-
387379
// The 'then' clause contributes a payload.
388380
numPayloads++;
389381

@@ -451,6 +443,14 @@ class BuilderClosureVisitor
451443
unsigned numPayloads, bool isOptional,
452444
bool isTopLevel = false) {
453445
assert(payloadIndex < numPayloads);
446+
447+
// First generate constraints for the conditions. This can introduce
448+
// variable bindings that will be used within the "then" branch.
449+
if (cs && cs->generateConstraints(ifStmt->getCond(), dc)) {
450+
hadError = true;
451+
return nullptr;
452+
}
453+
454454
// Make sure we recursively visit both sides even if we're not
455455
// building expressions.
456456

@@ -507,12 +507,6 @@ class BuilderClosureVisitor
507507
payloadIndex + 1, numPayloads, isOptional);
508508
}
509509

510-
// Generate constraints for the conditions.
511-
if (cs->generateConstraints(ifStmt->getCond(), dc)) {
512-
hadError = true;
513-
return nullptr;
514-
}
515-
516510
// The operand should have optional type if we had optional results,
517511
// so we just need to call `buildIf` now, since we're at the top level.
518512
if (isOptional && isTopLevel) {
@@ -945,8 +939,16 @@ class BuilderClosureRewriter
945939
continue;
946940
}
947941

948-
case StmtConditionElement::CK_PatternBinding:
949-
llvm_unreachable("unhandled statement condition");
942+
case StmtConditionElement::CK_PatternBinding: {
943+
ConstraintSystem &cs = solution.getConstraintSystem();
944+
auto target = *cs.getStmtConditionTarget(&condElement);
945+
auto resolvedTarget = rewriteTarget(target);
946+
if (resolvedTarget) {
947+
condElement.setInitializer(resolvedTarget->getAsExpr());
948+
condElement.setPattern(resolvedTarget->getInitializationPattern());
949+
}
950+
continue;
951+
}
950952
}
951953
}
952954
ifStmt->setCond(condition);

0 commit comments

Comments
 (0)