@@ -290,7 +290,7 @@ namespace {
290
290
public:
291
291
ConstraintSystem &cs;
292
292
DeclContext *dc;
293
- const Solution &solution;
293
+ Solution &solution;
294
294
bool SuppressDiagnostics;
295
295
296
296
// / Coerce the given tuple to another tuple type.
@@ -1792,7 +1792,7 @@ namespace {
1792
1792
}
1793
1793
1794
1794
public:
1795
- ExprRewriter (ConstraintSystem &cs, const Solution &solution,
1795
+ ExprRewriter (ConstraintSystem &cs, Solution &solution,
1796
1796
bool suppressDiagnostics)
1797
1797
: cs(cs), dc(cs.DC), solution(solution),
1798
1798
SuppressDiagnostics (suppressDiagnostics) {}
@@ -7142,6 +7142,10 @@ namespace {
7142
7142
7143
7143
// / Ignore declarations.
7144
7144
bool walkToDeclPre (Decl *decl) override { return false ; }
7145
+
7146
+ // / Rewrite the target, producing a new target.
7147
+ Optional<SolutionApplicationTarget>
7148
+ rewriteTarget (SolutionApplicationTarget target);
7145
7149
};
7146
7150
} // end anonymous namespace
7147
7151
@@ -7305,41 +7309,14 @@ static Optional<SolutionApplicationTarget> applySolutionToInitialization(
7305
7309
return resultTarget;
7306
7310
}
7307
7311
7308
- // / Apply a given solution to the expression, producing a fully
7309
- // / type-checked expression.
7310
- Optional<SolutionApplicationTarget> ConstraintSystem::applySolution (
7311
- Solution &solution, SolutionApplicationTarget target,
7312
- bool performingDiagnostics) {
7313
- // If any fixes needed to be applied to arrive at this solution, resolve
7314
- // them to specific expressions.
7315
- if (!solution.Fixes .empty ()) {
7316
- if (shouldSuppressDiagnostics ())
7317
- return None;
7318
-
7319
- bool diagnosedErrorsViaFixes = applySolutionFixes (solution);
7320
- // If all of the available fixes would result in a warning,
7321
- // we can go ahead and apply this solution to AST.
7322
- if (!llvm::all_of (solution.Fixes , [](const ConstraintFix *fix) {
7323
- return fix->isWarning ();
7324
- })) {
7325
- // If we already diagnosed any errors via fixes, that's it.
7326
- if (diagnosedErrorsViaFixes)
7327
- return None;
7328
-
7329
- // If we didn't manage to diagnose anything well, so fall back to
7330
- // diagnosing mining the system to construct a reasonable error message.
7331
- diagnoseFailureFor (target);
7332
- return None;
7333
- }
7334
- }
7335
-
7336
- ExprRewriter rewriter (*this , solution, shouldSuppressDiagnostics ());
7337
- ExprWalker walker (rewriter);
7312
+ Optional<SolutionApplicationTarget>
7313
+ ExprWalker::rewriteTarget (SolutionApplicationTarget target) {
7314
+ auto &solution = Rewriter.solution ;
7338
7315
7339
7316
// Apply the solution to the target.
7340
7317
SolutionApplicationTarget result = target;
7341
7318
if (auto expr = target.getAsExpr ()) {
7342
- Expr *rewrittenExpr = expr->walk (walker );
7319
+ Expr *rewrittenExpr = expr->walk (* this );
7343
7320
if (!rewrittenExpr)
7344
7321
return None;
7345
7322
@@ -7358,19 +7335,19 @@ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
7358
7335
auto fn = *target.getAsFunction ();
7359
7336
7360
7337
// Dig out the function builder transformation we applied.
7361
- auto transform = rewriter .getAppliedBuilderTransform (fn);
7338
+ auto transform = Rewriter .getAppliedBuilderTransform (fn);
7362
7339
assert (transform);
7363
7340
7364
7341
auto newBody = applyFunctionBuilderTransform (
7365
7342
solution, *transform, fn.getBody (), fn.getAsDeclContext (),
7366
7343
[&](Expr *expr) {
7367
- Expr *result = expr->walk (walker );
7344
+ Expr *result = expr->walk (* this );
7368
7345
if (result)
7369
7346
solution.setExprTypes (result);
7370
7347
return result;
7371
7348
},
7372
7349
[&](Expr *expr, Type toType, ConstraintLocator *locator) {
7373
- return rewriter .coerceToType (expr, toType, locator);
7350
+ return Rewriter .coerceToType (expr, toType, locator);
7374
7351
});
7375
7352
7376
7353
if (!newBody)
@@ -7379,26 +7356,8 @@ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
7379
7356
result.setFunctionBody (newBody);
7380
7357
}
7381
7358
7382
- // If we're re-typechecking an expression for diagnostics, don't
7383
- // visit closures that have non-single expression bodies.
7384
- if (!performingDiagnostics) {
7385
- bool hadError = false ;
7386
- for (auto *closure : walker.getClosuresToTypeCheck ())
7387
- hadError |= TypeChecker::typeCheckClosureBody (closure);
7388
-
7389
- // Tap expressions too; they should or should not be
7390
- // type-checked under the same conditions as closure bodies.
7391
- for (auto tuple : walker.getTapsToTypeCheck ()) {
7392
- auto tap = std::get<0 >(tuple);
7393
- auto tapDC = std::get<1 >(tuple);
7394
- hadError |= TypeChecker::typeCheckTapBody (tap, tapDC);
7395
- }
7396
-
7397
- // If any of them failed to type check, bail.
7398
- if (hadError)
7399
- return None;
7400
- }
7401
-
7359
+ // Follow-up tasks.
7360
+ auto &cs = solution.getConstraintSystem ();
7402
7361
if (auto resultExpr = result.getAsExpr ()) {
7403
7362
Expr *expr = target.getAsExpr ();
7404
7363
assert (expr && " Can't have expression result without expression target" );
@@ -7410,23 +7369,24 @@ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
7410
7369
auto shouldCoerceToContextualType = [&]() {
7411
7370
return convertType &&
7412
7371
!target.isOptionalSomePatternInit () &&
7413
- !(getType (resultExpr)->isUninhabited () &&
7414
- getContextualTypePurpose (target.getAsExpr ())
7372
+ !(solution. getType (resultExpr)->isUninhabited () &&
7373
+ cs. getContextualTypePurpose (target.getAsExpr ())
7415
7374
== CTP_ReturnSingleExpr);
7416
7375
};
7417
7376
7418
7377
// If we're supposed to convert the expression to some particular type,
7419
7378
// do so now.
7420
7379
if (shouldCoerceToContextualType ()) {
7421
- resultExpr = rewriter .coerceToType (resultExpr,
7422
- simplifyType (convertType),
7423
- getConstraintLocator (expr));
7424
- } else if (getType (resultExpr)->hasLValueType () &&
7380
+ resultExpr = Rewriter .coerceToType (resultExpr,
7381
+ solution. simplifyType (convertType),
7382
+ cs. getConstraintLocator (expr));
7383
+ } else if (cs. getType (resultExpr)->hasLValueType () &&
7425
7384
!target.isDiscardedExpr ()) {
7426
7385
// We referenced an lvalue. Load it.
7427
- resultExpr = rewriter.coerceToType (resultExpr,
7428
- getType (resultExpr)->getRValueType (),
7429
- getConstraintLocator (expr));
7386
+ resultExpr = Rewriter.coerceToType (
7387
+ resultExpr,
7388
+ cs.getType (resultExpr)->getRValueType (),
7389
+ cs.getConstraintLocator (expr));
7430
7390
}
7431
7391
7432
7392
if (!resultExpr)
@@ -7436,28 +7396,86 @@ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
7436
7396
// conversion.
7437
7397
if (FunctionType *autoclosureParamType =
7438
7398
target.getAsAutoclosureParamType ()) {
7439
- resultExpr = buildAutoClosureExpr (resultExpr, autoclosureParamType);
7399
+ resultExpr = cs. buildAutoClosureExpr (resultExpr, autoclosureParamType);
7440
7400
}
7441
7401
7442
7402
solution.setExprTypes (resultExpr);
7443
7403
result.setExpr (resultExpr);
7444
7404
7445
- if (Context.TypeCheckerOpts .DebugConstraintSolver ) {
7446
- auto &log = Context.TypeCheckerDebug ->getStream ();
7405
+ auto &ctx = cs.getASTContext ();
7406
+ if (ctx.TypeCheckerOpts .DebugConstraintSolver ) {
7407
+ auto &log = ctx.TypeCheckerDebug ->getStream ();
7447
7408
log << " ---Type-checked expression---\n " ;
7448
7409
resultExpr->dump (log);
7449
7410
log << " \n " ;
7450
7411
}
7451
7412
}
7452
7413
7414
+ return result;
7415
+ }
7416
+
7417
+ // / Apply a given solution to the expression, producing a fully
7418
+ // / type-checked expression.
7419
+ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution (
7420
+ Solution &solution, SolutionApplicationTarget target,
7421
+ bool performingDiagnostics) {
7422
+ // If any fixes needed to be applied to arrive at this solution, resolve
7423
+ // them to specific expressions.
7424
+ if (!solution.Fixes .empty ()) {
7425
+ if (shouldSuppressDiagnostics ())
7426
+ return None;
7427
+
7428
+ bool diagnosedErrorsViaFixes = applySolutionFixes (solution);
7429
+ // If all of the available fixes would result in a warning,
7430
+ // we can go ahead and apply this solution to AST.
7431
+ if (!llvm::all_of (solution.Fixes , [](const ConstraintFix *fix) {
7432
+ return fix->isWarning ();
7433
+ })) {
7434
+ // If we already diagnosed any errors via fixes, that's it.
7435
+ if (diagnosedErrorsViaFixes)
7436
+ return None;
7437
+
7438
+ // If we didn't manage to diagnose anything well, so fall back to
7439
+ // diagnosing mining the system to construct a reasonable error message.
7440
+ diagnoseFailureFor (target);
7441
+ return None;
7442
+ }
7443
+ }
7444
+
7445
+ ExprRewriter rewriter (*this , solution, shouldSuppressDiagnostics ());
7446
+ ExprWalker walker (rewriter);
7447
+ auto resultTarget = walker.rewriteTarget (target);
7448
+ if (!resultTarget)
7449
+ return None;
7450
+
7451
+ // If we're re-typechecking an expression for diagnostics, don't
7452
+ // visit closures that have non-single expression bodies.
7453
+ if (!performingDiagnostics) {
7454
+ bool hadError = false ;
7455
+ for (auto *closure : walker.getClosuresToTypeCheck ())
7456
+ hadError |= TypeChecker::typeCheckClosureBody (closure);
7457
+
7458
+ // Tap expressions too; they should or should not be
7459
+ // type-checked under the same conditions as closure bodies.
7460
+ for (auto tuple : walker.getTapsToTypeCheck ()) {
7461
+ auto tap = std::get<0 >(tuple);
7462
+ auto tapDC = std::get<1 >(tuple);
7463
+ hadError |= TypeChecker::typeCheckTapBody (tap, tapDC);
7464
+ }
7465
+
7466
+ // If any of them failed to type check, bail.
7467
+ if (hadError)
7468
+ return None;
7469
+ }
7470
+
7453
7471
rewriter.finalize ();
7454
7472
7455
- return result ;
7473
+ return resultTarget ;
7456
7474
}
7457
7475
7458
7476
Expr *Solution::coerceToType (Expr *expr, Type toType,
7459
7477
ConstraintLocator *locator,
7460
- Optional<Pattern*> typeFromPattern) const {
7478
+ Optional<Pattern*> typeFromPattern) {
7461
7479
auto &cs = getConstraintSystem ();
7462
7480
ExprRewriter rewriter (cs, *this , /* suppressDiagnostics=*/ false );
7463
7481
Expr *result = rewriter.coerceToType (expr, toType, locator, typeFromPattern);
0 commit comments