Skip to content

Commit 2bca013

Browse files
committed
Move "isDebugMode" into ConstraintSystem
This eliminates the final source of mutation of the TypeCheckerFlags on the ASTContext.
1 parent a5dcb1d commit 2bca013

14 files changed

+80
-68
lines changed

include/swift/AST/ASTContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ class ASTContext final {
241241
const LangOptions &LangOpts;
242242

243243
/// The type checker options.
244-
TypeCheckerOptions &TypeCheckerOpts;
244+
const TypeCheckerOptions &TypeCheckerOpts;
245245

246246
/// The search path options used by this AST context.
247247
SearchPathOptions &SearchPathOpts;

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8321,7 +8321,7 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
83218321
result.setExpr(resultExpr);
83228322

83238323
auto &ctx = cs.getASTContext();
8324-
if (ctx.TypeCheckerOpts.DebugConstraintSolver) {
8324+
if (cs.isDebugMode()) {
83258325
auto &log = ctx.TypeCheckerDebug->getStream();
83268326
log << "---Type-checked expression---\n";
83278327
resultExpr->dump(log);

lib/Sema/CSBindings.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ ConstraintSystem::determineBestBindings() {
107107

108108
inferTransitiveSupertypeBindings(cache, bindings);
109109

110-
if (getASTContext().TypeCheckerOpts.DebugConstraintSolver) {
110+
if (isDebugMode()) {
111111
auto &log = getASTContext().TypeCheckerDebug->getStream();
112112
bindings.dump(typeVar, log, solverState->depth * 2);
113113
}

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4364,7 +4364,7 @@ bool ConstraintSystem::generateConstraints(
43644364
target = *resultTarget;
43654365
}
43664366

4367-
if (getASTContext().TypeCheckerOpts.DebugConstraintSolver) {
4367+
if (isDebugMode()) {
43684368
auto &log = getASTContext().TypeCheckerDebug->getStream();
43694369
log << "---Initial constraints for the given expression---\n";
43704370
print(log, expr);

lib/Sema/CSRanking.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void ConstraintSystem::increaseScore(ScoreKind kind, unsigned value) {
3535
unsigned index = static_cast<unsigned>(kind);
3636
CurrentScore.Data[index] += value;
3737

38-
if (getASTContext().TypeCheckerOpts.DebugConstraintSolver && value > 0) {
38+
if (isDebugMode() && value > 0) {
3939
auto &log = getASTContext().TypeCheckerDebug->getStream();
4040
if (solverState)
4141
log.indent(solverState->depth * 2);
@@ -102,7 +102,7 @@ bool ConstraintSystem::worseThanBestSolution() const {
102102
CurrentScore <= *solverState->BestScore)
103103
return false;
104104

105-
if (getASTContext().TypeCheckerOpts.DebugConstraintSolver) {
105+
if (isDebugMode()) {
106106
auto &log = getASTContext().TypeCheckerDebug->getStream();
107107
log.indent(solverState->depth * 2)
108108
<< "(solution is worse than the best solution)\n";
@@ -386,7 +386,9 @@ bool CompareDeclSpecializationRequest::evaluate(
386386
Evaluator &eval, DeclContext *dc, ValueDecl *decl1, ValueDecl *decl2,
387387
bool isDynamicOverloadComparison) const {
388388
auto &C = decl1->getASTContext();
389-
if (C.TypeCheckerOpts.DebugConstraintSolver) {
389+
// Construct a constraint system to compare the two declarations.
390+
ConstraintSystem cs(dc, ConstraintSystemOptions());
391+
if (cs.isDebugMode()) {
390392
auto &log = C.TypeCheckerDebug->getStream();
391393
log << "Comparing declarations\n";
392394
decl1->print(log);
@@ -397,8 +399,8 @@ bool CompareDeclSpecializationRequest::evaluate(
397399
log << ")\n";
398400
}
399401

400-
auto completeResult = [&C](bool result) {
401-
if (C.TypeCheckerOpts.DebugConstraintSolver) {
402+
auto completeResult = [&C, &cs](bool result) {
403+
if (cs.isDebugMode()) {
402404
auto &log = C.TypeCheckerDebug->getStream();
403405
log << "comparison result: " << (result ? "better" : "not better")
404406
<< "\n";
@@ -499,8 +501,6 @@ bool CompareDeclSpecializationRequest::evaluate(
499501
return cs.openType(type, replacements);
500502
};
501503

502-
// Construct a constraint system to compare the two declarations.
503-
ConstraintSystem cs(dc, ConstraintSystemOptions());
504504
bool knownNonSubtype = false;
505505

506506
auto *locator = cs.getConstraintLocator({});
@@ -737,7 +737,7 @@ static void addKeyPathDynamicMemberOverloads(
737737
SolutionCompareResult ConstraintSystem::compareSolutions(
738738
ConstraintSystem &cs, ArrayRef<Solution> solutions,
739739
const SolutionDiff &diff, unsigned idx1, unsigned idx2) {
740-
if (cs.getASTContext().TypeCheckerOpts.DebugConstraintSolver) {
740+
if (cs.isDebugMode()) {
741741
auto &log = cs.getASTContext().TypeCheckerDebug->getStream();
742742
log.indent(cs.solverState->depth * 2)
743743
<< "comparing solutions " << idx1 << " and " << idx2 <<"\n";
@@ -1261,7 +1261,7 @@ ConstraintSystem::findBestSolution(SmallVectorImpl<Solution> &viable,
12611261
if (viable.size() == 1)
12621262
return 0;
12631263

1264-
if (getASTContext().TypeCheckerOpts.DebugConstraintSolver) {
1264+
if (isDebugMode()) {
12651265
auto &log = getASTContext().TypeCheckerDebug->getStream();
12661266
log.indent(solverState->depth * 2)
12671267
<< "Comparing " << viable.size() << " viable solutions\n";

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8148,7 +8148,7 @@ bool ConstraintSystem::simplifyAppliedOverloadsImpl(
81488148
// If we have a common result type, bind the expected result type to it.
81498149
if (commonResultType && !commonResultType->is<ErrorType>()) {
81508150
ASTContext &ctx = getASTContext();
8151-
if (ctx.TypeCheckerOpts.DebugConstraintSolver) {
8151+
if (isDebugMode()) {
81528152
auto &log = ctx.TypeCheckerDebug->getStream();
81538153
log.indent(solverState ? solverState->depth * 2 : 0)
81548154
<< "(common result type for $T" << fnTypeVar->getID() << " is "
@@ -9290,7 +9290,7 @@ static bool isAugmentingFix(ConstraintFix *fix) {
92909290

92919291
bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact) {
92929292
auto &ctx = getASTContext();
9293-
if (ctx.TypeCheckerOpts.DebugConstraintSolver) {
9293+
if (isDebugMode()) {
92949294
auto &log = ctx.TypeCheckerDebug->getStream();
92959295
log.indent(solverState ? solverState->depth * 2 : 0)
92969296
<< "(attempting fix ";

lib/Sema/CSSolver.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,10 @@ ConstraintSystem::SolverState::SolverState(
375375
// If we're supposed to debug a specific constraint solver attempt,
376376
// turn on debugging now.
377377
ASTContext &ctx = CS.getASTContext();
378-
auto &tyOpts = ctx.TypeCheckerOpts;
379-
OldDebugConstraintSolver = tyOpts.DebugConstraintSolver;
378+
const auto &tyOpts = ctx.TypeCheckerOpts;
380379
if (tyOpts.DebugConstraintSolverAttempt &&
381380
tyOpts.DebugConstraintSolverAttempt == SolutionAttempt) {
382-
tyOpts.DebugConstraintSolver = true;
381+
CS.Options |= ConstraintSystemFlags::DebugConstraints;
383382
llvm::raw_ostream &dbgOut = ctx.TypeCheckerDebug->getStream();
384383
dbgOut << "---Constraint system #" << SolutionAttempt << "---\n";
385384
CS.print(dbgOut);
@@ -420,9 +419,14 @@ ConstraintSystem::SolverState::~SolverState() {
420419
CS.activateConstraint(constraint);
421420
}
422421

423-
// Restore debugging state.
424-
TypeCheckerOptions &tyOpts = CS.getASTContext().TypeCheckerOpts;
425-
tyOpts.DebugConstraintSolver = OldDebugConstraintSolver;
422+
// If global constraing debugging is off and we are finished logging the
423+
// current solution attempt, switch debugging back off.
424+
const auto &tyOpts = CS.getASTContext().TypeCheckerOpts;
425+
if (!tyOpts.DebugConstraintSolver &&
426+
tyOpts.DebugConstraintSolverAttempt &&
427+
tyOpts.DebugConstraintSolverAttempt == SolutionAttempt) {
428+
CS.Options -= ConstraintSystemFlags::DebugConstraints;
429+
}
426430

427431
// Write our local statistics back to the overall statistics.
428432
#define CS_STATISTIC(Name, Description) JOIN2(Overall,Name) += Name;
@@ -627,8 +631,8 @@ bool ConstraintSystem::Candidate::solve(
627631
return false;
628632

629633
auto &ctx = cs.getASTContext();
630-
if (ctx.TypeCheckerOpts.DebugConstraintSolver) {
631-
auto &log = cs.getASTContext().TypeCheckerDebug->getStream();
634+
if (cs.isDebugMode()) {
635+
auto &log = ctx.TypeCheckerDebug->getStream();
632636
log << "--- Solving candidate for shrinking at ";
633637
auto R = E->getSourceRange();
634638
if (R.isValid()) {
@@ -664,8 +668,8 @@ bool ConstraintSystem::Candidate::solve(
664668
cs.solveImpl(solutions);
665669
}
666670

667-
if (ctx.TypeCheckerOpts.DebugConstraintSolver) {
668-
auto &log = cs.getASTContext().TypeCheckerDebug->getStream();
671+
if (cs.isDebugMode()) {
672+
auto &log = ctx.TypeCheckerDebug->getStream();
669673
if (solutions.empty()) {
670674
log << "--- No Solutions ---\n";
671675
} else {
@@ -1130,14 +1134,15 @@ Optional<std::vector<Solution>> ConstraintSystem::solve(
11301134
SolutionApplicationTarget &target,
11311135
FreeTypeVariableBinding allowFreeTypeVariables
11321136
) {
1133-
llvm::SaveAndRestore<bool> debugForExpr(
1134-
getASTContext().TypeCheckerOpts.DebugConstraintSolver,
1135-
debugConstraintSolverForTarget(getASTContext(), target));
1137+
llvm::SaveAndRestore<ConstraintSystemOptions> debugForExpr(Options);
1138+
if (debugConstraintSolverForTarget(getASTContext(), target)) {
1139+
Options |= ConstraintSystemFlags::DebugConstraints;
1140+
}
11361141

11371142
/// Dump solutions for debugging purposes.
11381143
auto dumpSolutions = [&](const SolutionResult &result) {
11391144
// Debug-print the set of solutions.
1140-
if (getASTContext().TypeCheckerOpts.DebugConstraintSolver) {
1145+
if (isDebugMode()) {
11411146
auto &log = getASTContext().TypeCheckerDebug->getStream();
11421147
if (result.getKind() == SolutionResult::Success) {
11431148
log << "---Solution---\n";
@@ -1224,7 +1229,7 @@ Optional<std::vector<Solution>> ConstraintSystem::solve(
12241229
SolutionResult
12251230
ConstraintSystem::solveImpl(SolutionApplicationTarget &target,
12261231
FreeTypeVariableBinding allowFreeTypeVariables) {
1227-
if (getASTContext().TypeCheckerOpts.DebugConstraintSolver) {
1232+
if (isDebugMode()) {
12281233
auto &log = getASTContext().TypeCheckerDebug->getStream();
12291234
log << "---Constraint solving at ";
12301235
auto R = target.getSourceRange();
@@ -1272,7 +1277,7 @@ bool ConstraintSystem::solve(SmallVectorImpl<Solution> &solutions,
12721277
// Solve the system.
12731278
solveImpl(solutions);
12741279

1275-
if (getASTContext().TypeCheckerOpts.DebugConstraintSolver) {
1280+
if (isDebugMode()) {
12761281
auto &log = getASTContext().TypeCheckerDebug->getStream();
12771282
log << "---Solver statistics---\n";
12781283
log << "Total number of scopes explored: " << solverState->NumStatesExplored << "\n";
@@ -1409,7 +1414,7 @@ ConstraintSystem::filterDisjunction(
14091414
continue;
14101415
}
14111416

1412-
if (ctx.TypeCheckerOpts.DebugConstraintSolver) {
1417+
if (isDebugMode()) {
14131418
auto &log = ctx.TypeCheckerDebug->getStream();
14141419
log.indent(solverState ? solverState->depth * 2 : 0)
14151420
<< "(disabled disjunction term ";
@@ -1470,7 +1475,7 @@ ConstraintSystem::filterDisjunction(
14701475
recordDisjunctionChoice(disjunction->getLocator(), choiceIdx);
14711476
}
14721477

1473-
if (ctx.TypeCheckerOpts.DebugConstraintSolver) {
1478+
if (isDebugMode()) {
14741479
auto &log = ctx.TypeCheckerDebug->getStream();
14751480
log.indent(solverState ? solverState->depth * 2 : 0)
14761481
<< "(introducing single enabled disjunction term ";

lib/Sema/CSStep.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void SplitterStep::computeFollowupSteps(
100100
return;
101101
}
102102

103-
if (isDebugMode()) {
103+
if (CS.isDebugMode()) {
104104
auto &log = getDebugLogger();
105105
// Verify that the constraint graph is valid.
106106
CG.verify();
@@ -238,7 +238,7 @@ bool SplitterStep::mergePartialSolutions() const {
238238
// Finalize this solution.
239239
auto solution = CS.finalize();
240240
solutionMemory += solution.getTotalMemory();
241-
if (isDebugMode())
241+
if (CS.isDebugMode())
242242
getDebugLogger() << "(composed solution " << CS.CurrentScore << ")\n";
243243

244244
// Save this solution.
@@ -391,7 +391,7 @@ StepResult ComponentStep::take(bool prevFailed) {
391391
}
392392

393393
auto solution = CS.finalize();
394-
if (isDebugMode())
394+
if (CS.isDebugMode())
395395
getDebugLogger() << "(found solution " << getCurrentScore() << ")\n";
396396

397397
Solutions.push_back(std::move(solution));
@@ -408,7 +408,7 @@ StepResult ComponentStep::finalize(bool isSuccess) {
408408
// Rewind all modifications done to constraint system.
409409
ComponentScope.reset();
410410

411-
if (isDebugMode()) {
411+
if (CS.isDebugMode()) {
412412
auto &log = getDebugLogger();
413413
log << (isSuccess ? "finished" : "failed") << " component #" << Index
414414
<< ")\n";
@@ -440,7 +440,7 @@ StepResult ComponentStep::finalize(bool isSuccess) {
440440

441441
void TypeVariableStep::setup() {
442442
++CS.solverState->NumTypeVariablesBound;
443-
if (isDebugMode()) {
443+
if (CS.isDebugMode()) {
444444
PrintOptions PO;
445445
PO.PrintTypesForDebugging = true;
446446
auto &log = getDebugLogger();
@@ -478,7 +478,7 @@ StepResult TypeVariableStep::resume(bool prevFailed) {
478478
// Rewind back all of the changes made to constraint system.
479479
ActiveChoice.reset();
480480

481-
if (isDebugMode())
481+
if (CS.isDebugMode())
482482
getDebugLogger() << ")\n";
483483

484484
// Let's check if we should stop right before
@@ -517,7 +517,7 @@ StepResult DisjunctionStep::resume(bool prevFailed) {
517517
// Rewind back the constraint system information.
518518
ActiveChoice.reset();
519519

520-
if (isDebugMode())
520+
if (CS.isDebugMode())
521521
getDebugLogger() << ")\n";
522522

523523
// Attempt next disjunction choice (if any left).
@@ -530,7 +530,7 @@ bool DisjunctionStep::shouldSkip(const DisjunctionChoice &choice) const {
530530
bool attemptFixes = CS.shouldAttemptFixes();
531531
// Enable all disabled choices in "diagnostic" mode.
532532
if (!attemptFixes && choice.isDisabled()) {
533-
if (isDebugMode()) {
533+
if (CS.isDebugMode()) {
534534
auto &log = getDebugLogger();
535535
log << "(skipping ";
536536
choice.print(log, &ctx.SourceMgr);

lib/Sema/CSStep.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,6 @@ class SolverStep {
231231
CS.filterSolutions(solutions, minimize);
232232
}
233233

234-
/// Check whether constraint solver is running in "debug" mode,
235-
/// which should output diagnostic information.
236-
bool isDebugMode() const {
237-
return CS.getASTContext().TypeCheckerOpts.DebugConstraintSolver;
238-
}
239-
240234
llvm::raw_ostream &getDebugLogger(bool indent = true) const {
241235
auto &log = CS.getASTContext().TypeCheckerDebug->getStream();
242236
return indent ? log.indent(CS.solverState->depth * 2) : log;
@@ -471,7 +465,7 @@ class ComponentStep final : public SolverStep {
471465
if (IsSingle)
472466
return;
473467

474-
if (isDebugMode())
468+
if (CS.isDebugMode())
475469
getDebugLogger() << "(solving component #" << Index << '\n';
476470

477471
ComponentScope = std::make_unique<Scope>(*this);
@@ -515,7 +509,7 @@ template <typename P> class BindingStep : public SolverStep {
515509
if (shouldStopAt(*choice))
516510
break;
517511

518-
if (isDebugMode()) {
512+
if (CS.isDebugMode()) {
519513
auto &log = getDebugLogger();
520514
log << "(attempting ";
521515
choice->print(log, &CS.getASTContext().SourceMgr);
@@ -530,7 +524,7 @@ template <typename P> class BindingStep : public SolverStep {
530524
}
531525
}
532526

533-
if (isDebugMode())
527+
if (CS.isDebugMode())
534528
getDebugLogger() << ")\n";
535529

536530
// If this binding didn't match, let's check if we've attempted

lib/Sema/ConstraintGraph.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ namespace {
872872
contractedCycle = false;
873873
for (const auto &edge : cycleEdges) {
874874
if (unionSets(edge.first, edge.second)) {
875-
if (ctx.TypeCheckerOpts.DebugConstraintSolver) {
875+
if (cs.isDebugMode()) {
876876
auto &log = ctx.TypeCheckerDebug->getStream();
877877
if (cs.solverState)
878878
log.indent(cs.solverState->depth * 2);
@@ -1155,7 +1155,7 @@ bool ConstraintGraph::contractEdges() {
11551155
rep2->getImpl().canBindToLValue()) ||
11561156
// Allow l-value contractions when binding parameter types.
11571157
isParamBindingConstraint)) {
1158-
if (CS.getASTContext().TypeCheckerOpts.DebugConstraintSolver) {
1158+
if (CS.isDebugMode()) {
11591159
auto &log = CS.getASTContext().TypeCheckerDebug->getStream();
11601160
if (CS.solverState)
11611161
log.indent(CS.solverState->depth * 2);

0 commit comments

Comments
 (0)