@@ -324,18 +324,27 @@ class BuilderClosureVisitor
324
324
CONTROL_FLOW_STMT (Yield)
325
325
CONTROL_FLOW_STMT (Defer)
326
326
327
- static Expr *getTrivialBooleanCondition (StmtCondition condition) {
328
- if (condition.size () != 1 )
329
- return nullptr ;
327
+ // / Whether we can handle all of the conditions for this statement.
328
+ static bool canHandleStmtConditions (StmtCondition condition) {
329
+ for (const auto &element : condition) {
330
+ switch (element.getKind ()) {
331
+ case StmtConditionElement::CK_Boolean:
332
+ continue ;
330
333
331
- return condition.front ().getBooleanOrNull ();
334
+ case StmtConditionElement::CK_PatternBinding:
335
+ case StmtConditionElement::CK_Availability:
336
+ return false ;
337
+ }
338
+ }
339
+
340
+ return true ;
332
341
}
333
342
334
343
static bool isBuildableIfChainRecursive (IfStmt *ifStmt,
335
344
unsigned &numPayloads,
336
345
bool &isOptional) {
337
- // The conditional must be trivial .
338
- if (!getTrivialBooleanCondition (ifStmt->getCond ()))
346
+ // Check whether we can handle the conditional .
347
+ if (!canHandleStmtConditions (ifStmt->getCond ()))
339
348
return false ;
340
349
341
350
// The 'then' clause contributes a payload.
@@ -461,26 +470,37 @@ class BuilderClosureVisitor
461
470
payloadIndex + 1 , numPayloads, isOptional);
462
471
}
463
472
464
- // Generate constraints for the various subexpressions.
465
- auto condExpr = getTrivialBooleanCondition (ifStmt->getCond ());
466
- assert (condExpr && " Cannot get here without a trivial Boolean condition" );
467
- condExpr = cs->generateConstraints (condExpr, dc);
468
- if (!condExpr) {
469
- hadError = true ;
470
- return nullptr ;
471
- }
472
-
473
473
// Condition must convert to Bool.
474
474
// FIXME: This should be folded into constraint generation for conditions.
475
475
auto boolDecl = ctx.getBoolDecl ();
476
476
if (!boolDecl) {
477
477
hadError = true ;
478
478
return nullptr ;
479
479
}
480
- cs->addConstraint (ConstraintKind::Conversion,
481
- cs->getType (condExpr),
482
- boolDecl->getDeclaredType (),
483
- cs->getConstraintLocator (condExpr));
480
+
481
+ // Generate constraints for the conditions.
482
+ for (const auto &condElement : ifStmt->getCond ()) {
483
+ switch (condElement.getKind ()) {
484
+ case StmtConditionElement::CK_Boolean: {
485
+ Expr *condExpr = condElement.getBoolean ();
486
+ condExpr = cs->generateConstraints (condExpr, dc);
487
+ if (!condExpr) {
488
+ hadError = true ;
489
+ return nullptr ;
490
+ }
491
+
492
+ cs->addConstraint (ConstraintKind::Conversion,
493
+ cs->getType (condExpr),
494
+ boolDecl->getDeclaredType (),
495
+ cs->getConstraintLocator (condExpr));
496
+ continue ;
497
+ }
498
+
499
+ case StmtConditionElement::CK_PatternBinding:
500
+ case StmtConditionElement::CK_Availability:
501
+ llvm_unreachable (" unhandled statement condition" );
502
+ }
503
+ }
484
504
485
505
// The operand should have optional type if we had optional results,
486
506
// so we just need to call `buildIf` now, since we're at the top level.
@@ -850,19 +870,29 @@ class BuilderClosureRewriter
850
870
851
871
Stmt *visitIfStmt (IfStmt *ifStmt, FunctionBuilderTarget target) {
852
872
// Rewrite the condition.
853
- // FIXME: We should handle the whole condition within the type system.
854
- auto cond = ifStmt->getCond ();
855
- auto condExpr = cond.front ().getBoolean ();
856
- auto finalCondExpr = rewriteExpr (condExpr);
857
-
858
- // Load the condition if needed.
859
- if (finalCondExpr->getType ()->is <LValueType>()) {
860
- auto &cs = solution.getConstraintSystem ();
861
- finalCondExpr = cs.addImplicitLoadExpr (finalCondExpr);
862
- }
873
+ auto condition = ifStmt->getCond ();
874
+ for (auto &condElement : condition) {
875
+ switch (condElement.getKind ()) {
876
+ case StmtConditionElement::CK_Boolean: {
877
+ auto condExpr = condElement.getBoolean ();
878
+ auto finalCondExpr = rewriteExpr (condExpr);
879
+
880
+ // Load the condition if needed.
881
+ if (finalCondExpr->getType ()->is <LValueType>()) {
882
+ auto &cs = solution.getConstraintSystem ();
883
+ finalCondExpr = cs.addImplicitLoadExpr (finalCondExpr);
884
+ }
885
+
886
+ condElement.setBoolean (finalCondExpr);
887
+ continue ;
888
+ }
863
889
864
- cond.front ().setBoolean (finalCondExpr);
865
- ifStmt->setCond (cond);
890
+ case StmtConditionElement::CK_PatternBinding:
891
+ case StmtConditionElement::CK_Availability:
892
+ llvm_unreachable (" unhandled statement condition" );
893
+ }
894
+ }
895
+ ifStmt->setCond (condition);
866
896
867
897
assert (target.kind == FunctionBuilderTarget::TemporaryVar);
868
898
auto temporaryVar = target.captured .first ;
0 commit comments