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