@@ -7093,6 +7093,48 @@ bool swift::exprNeedsParensAfterAddingNilCoalescing(DeclContext *DC,
7093
7093
}
7094
7094
7095
7095
namespace {
7096
+ class SetExprTypes : public ASTWalker {
7097
+ const Solution &solution;
7098
+
7099
+ public:
7100
+ explicit SetExprTypes (const Solution &solution)
7101
+ : solution(solution) {}
7102
+
7103
+ Expr *walkToExprPost (Expr *expr) override {
7104
+ auto &cs = solution.getConstraintSystem ();
7105
+ auto exprType = cs.getType (expr);
7106
+ exprType = solution.simplifyType (exprType);
7107
+ // assert((!expr->getType() || expr->getType()->isEqual(exprType)) &&
7108
+ // "Mismatched types!");
7109
+ assert (!exprType->hasTypeVariable () &&
7110
+ " Should not write type variable into expression!" );
7111
+ expr->setType (exprType);
7112
+
7113
+ if (auto kp = dyn_cast<KeyPathExpr>(expr)) {
7114
+ for (auto i : indices (kp->getComponents ())) {
7115
+ Type componentType;
7116
+ if (cs.hasType (kp, i)) {
7117
+ componentType = solution.simplifyType (cs.getType (kp, i));
7118
+ assert (!componentType->hasTypeVariable () &&
7119
+ " Should not write type variable into key-path component" );
7120
+ }
7121
+
7122
+ kp->getMutableComponents ()[i].setComponentType (componentType);
7123
+ }
7124
+ }
7125
+
7126
+ return expr;
7127
+ }
7128
+
7129
+ // / Ignore statements.
7130
+ std::pair<bool , Stmt *> walkToStmtPre (Stmt *stmt) override {
7131
+ return { false , stmt };
7132
+ }
7133
+
7134
+ // / Ignore declarations.
7135
+ bool walkToDeclPre (Decl *decl) override { return false ; }
7136
+ };
7137
+
7096
7138
class ExprWalker : public ASTWalker {
7097
7139
ExprRewriter &Rewriter;
7098
7140
SmallVector<ClosureExpr *, 4 > ClosuresToTypeCheck;
@@ -7395,6 +7437,45 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
7395
7437
} else {
7396
7438
result.setExpr (rewrittenExpr);
7397
7439
}
7440
+ } else if (auto stmtCondition = target.getAsStmtCondition ()) {
7441
+ for (auto &condElement : *stmtCondition) {
7442
+ switch (condElement.getKind ()) {
7443
+ case StmtConditionElement::CK_Availability:
7444
+ continue ;
7445
+
7446
+ case StmtConditionElement::CK_Boolean: {
7447
+ auto condExpr = condElement.getBoolean ();
7448
+ auto finalCondExpr = condExpr->walk (*this );
7449
+ if (!finalCondExpr)
7450
+ return None;
7451
+
7452
+ // Load the condition if needed.
7453
+ solution.setExprTypes (finalCondExpr);
7454
+ if (finalCondExpr->getType ()->hasLValueType ()) {
7455
+ ASTContext &ctx = solution.getConstraintSystem ().getASTContext ();
7456
+ finalCondExpr = TypeChecker::addImplicitLoadExpr (ctx, finalCondExpr);
7457
+ }
7458
+
7459
+ condElement.setBoolean (finalCondExpr);
7460
+ continue ;
7461
+ }
7462
+
7463
+ case StmtConditionElement::CK_PatternBinding: {
7464
+ ConstraintSystem &cs = solution.getConstraintSystem ();
7465
+ auto target = *cs.getStmtConditionTarget (&condElement);
7466
+ auto resolvedTarget = rewriteTarget (target);
7467
+ if (!resolvedTarget)
7468
+ return None;
7469
+
7470
+ solution.setExprTypes (resolvedTarget->getAsExpr ());
7471
+ condElement.setInitializer (resolvedTarget->getAsExpr ());
7472
+ condElement.setPattern (resolvedTarget->getInitializationPattern ());
7473
+ continue ;
7474
+ }
7475
+ }
7476
+ }
7477
+
7478
+ return target;
7398
7479
} else {
7399
7480
auto fn = *target.getAsFunction ();
7400
7481
@@ -7408,7 +7489,7 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
7408
7489
auto resultTarget = rewriteTarget (target);
7409
7490
if (resultTarget) {
7410
7491
if (auto expr = resultTarget->getAsExpr ())
7411
- Rewriter. solution .setExprTypes (expr);
7492
+ solution.setExprTypes (expr);
7412
7493
}
7413
7494
7414
7495
return resultTarget;
@@ -7547,50 +7628,6 @@ Expr *Solution::coerceToType(Expr *expr, Type toType,
7547
7628
return result;
7548
7629
}
7549
7630
7550
- namespace {
7551
- class SetExprTypes : public ASTWalker {
7552
- const Solution &solution;
7553
-
7554
- public:
7555
- explicit SetExprTypes (const Solution &solution)
7556
- : solution(solution) {}
7557
-
7558
- Expr *walkToExprPost (Expr *expr) override {
7559
- auto &cs = solution.getConstraintSystem ();
7560
- auto exprType = cs.getType (expr);
7561
- exprType = solution.simplifyType (exprType);
7562
- // assert((!expr->getType() || expr->getType()->isEqual(exprType)) &&
7563
- // "Mismatched types!");
7564
- assert (!exprType->hasTypeVariable () &&
7565
- " Should not write type variable into expression!" );
7566
- expr->setType (exprType);
7567
-
7568
- if (auto kp = dyn_cast<KeyPathExpr>(expr)) {
7569
- for (auto i : indices (kp->getComponents ())) {
7570
- Type componentType;
7571
- if (cs.hasType (kp, i)) {
7572
- componentType = solution.simplifyType (cs.getType (kp, i));
7573
- assert (!componentType->hasTypeVariable () &&
7574
- " Should not write type variable into key-path component" );
7575
- }
7576
-
7577
- kp->getMutableComponents ()[i].setComponentType (componentType);
7578
- }
7579
- }
7580
-
7581
- return expr;
7582
- }
7583
-
7584
- // / Ignore statements.
7585
- std::pair<bool , Stmt *> walkToStmtPre (Stmt *stmt) override {
7586
- return { false , stmt };
7587
- }
7588
-
7589
- // / Ignore declarations.
7590
- bool walkToDeclPre (Decl *decl) override { return false ; }
7591
- };
7592
- }
7593
-
7594
7631
ProtocolConformanceRef Solution::resolveConformance (
7595
7632
ConstraintLocator *locator, ProtocolDecl *proto) {
7596
7633
for (const auto &conformance : Conformances) {
@@ -7705,5 +7742,11 @@ SolutionApplicationTarget SolutionApplicationTarget::walk(ASTWalker &walker) {
7705
7742
return SolutionApplicationTarget (
7706
7743
*getAsFunction (),
7707
7744
cast_or_null<BraceStmt>(getFunctionBody ()->walk (walker)));
7745
+
7746
+ case Kind::stmtCondition:
7747
+ for (auto &condElement : stmtCondition.stmtCondition ) {
7748
+ condElement = *condElement.walk (walker);
7749
+ }
7750
+ return *this ;
7708
7751
}
7709
7752
}
0 commit comments