Skip to content

Commit fb8adb0

Browse files
authored
Merge pull request swiftlang#19101 from xedin/move-allow-free-typevars-into-state
[ConstraintSystem] NFC: Move `allowFreeTypeVariableBindings` into `So…
2 parents dc1bc82 + d560b36 commit fb8adb0

File tree

3 files changed

+54
-72
lines changed

3 files changed

+54
-72
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 32 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,14 @@ Optional<Type> ConstraintSystem::checkTypeOfBinding(TypeVariableType *typeVar,
123123
return type;
124124
}
125125

126-
Solution ConstraintSystem::finalize(
127-
FreeTypeVariableBinding allowFreeTypeVariables) {
126+
Solution ConstraintSystem::finalize() {
127+
assert(solverState);
128+
128129
// Create the solution.
129130
Solution solution(*this, CurrentScore);
130131

131132
// Update the best score we've seen so far.
132-
if (solverState && !retainAllSolutions()) {
133+
if (!retainAllSolutions()) {
133134
assert(TC.getLangOpts().DisableConstraintSolverPerformanceHacks ||
134135
!solverState->BestScore || CurrentScore <= *solverState->BestScore);
135136

@@ -142,7 +143,7 @@ Solution ConstraintSystem::finalize(
142143
if (getFixedType(tv))
143144
continue;
144145

145-
switch (allowFreeTypeVariables) {
146+
switch (solverState->AllowFreeTypeVariables) {
146147
case FreeTypeVariableBinding::Disallow:
147148
llvm_unreachable("Solver left free type variables");
148149

@@ -386,9 +387,10 @@ void truncate(SmallVectorImpl<T> &vec, unsigned newSize) {
386387

387388
} // end anonymous namespace
388389

389-
ConstraintSystem::SolverState::SolverState(Expr *const expr,
390-
ConstraintSystem &cs)
391-
: CS(cs) {
390+
ConstraintSystem::SolverState::SolverState(
391+
Expr *const expr, ConstraintSystem &cs,
392+
FreeTypeVariableBinding allowFreeTypeVariables)
393+
: CS(cs), AllowFreeTypeVariables(allowFreeTypeVariables) {
392394
assert(!CS.solverState &&
393395
"Constraint system should not already have solver state!");
394396
CS.solverState = this;
@@ -520,8 +522,7 @@ ConstraintSystem::SolverScope::~SolverScope() {
520522
bool ConstraintSystem::tryTypeVariableBindings(
521523
TypeVariableType *typeVar,
522524
ArrayRef<ConstraintSystem::PotentialBinding> initialBindings,
523-
SmallVectorImpl<Solution> &solutions,
524-
FreeTypeVariableBinding allowFreeTypeVariables) {
525+
SmallVectorImpl<Solution> &solutions) {
525526
auto &TC = getTypeChecker();
526527
bool anySolved = false;
527528
bool sawFirstLiteralConstraint = false;
@@ -558,7 +559,7 @@ bool ConstraintSystem::tryTypeVariableBindings(
558559
if (binding.isDefaultableBinding())
559560
DefaultedConstraints.push_back(binding.DefaultableBinding);
560561

561-
return !solveRec(solutions, allowFreeTypeVariables);
562+
return !solveRec(solutions);
562563
};
563564

564565
if (TC.getLangOpts().DebugConstraintSolver) {
@@ -713,12 +714,12 @@ bool ConstraintSystem::Candidate::solve(
713714
// Try to solve the system and record all available solutions.
714715
llvm::SmallVector<Solution, 2> solutions;
715716
{
716-
SolverState state(E, cs);
717+
SolverState state(E, cs, FreeTypeVariableBinding::Allow);
717718

718719
// Use solveRec() instead of solve() in here, because solve()
719720
// would try to deduce the best solution, which we don't
720721
// really want. Instead, we want the reduced set of domain choices.
721-
cs.solveRec(solutions, FreeTypeVariableBinding::Allow);
722+
cs.solveRec(solutions);
722723
}
723724

724725
if (TC.getLangOpts().DebugConstraintSolver) {
@@ -1302,10 +1303,10 @@ bool ConstraintSystem::solve(Expr *const expr,
13021303
SmallVectorImpl<Solution> &solutions,
13031304
FreeTypeVariableBinding allowFreeTypeVariables) {
13041305
// Set up solver state.
1305-
SolverState state(expr, *this);
1306+
SolverState state(expr, *this, allowFreeTypeVariables);
13061307

13071308
// Solve the system.
1308-
solveRec(solutions, allowFreeTypeVariables);
1309+
solveRec(solutions);
13091310

13101311
if (TC.getLangOpts().DebugConstraintSolver) {
13111312
auto &log = getASTContext().TypeCheckerDebug->getStream();
@@ -1330,8 +1331,7 @@ bool ConstraintSystem::solve(Expr *const expr,
13301331
return solutions.empty() || getExpressionTooComplex(solutions);
13311332
}
13321333

1333-
bool ConstraintSystem::solveRec(SmallVectorImpl<Solution> &solutions,
1334-
FreeTypeVariableBinding allowFreeTypeVariables){
1334+
bool ConstraintSystem::solveRec(SmallVectorImpl<Solution> &solutions) {
13351335
// If we already failed, or simplification fails, we're done.
13361336
if (failedConstraint || simplify())
13371337
return true;
@@ -1347,11 +1347,10 @@ bool ConstraintSystem::solveRec(SmallVectorImpl<Solution> &solutions,
13471347

13481348
// If any free type variables remain and we're not allowed to have them,
13491349
// fail.
1350-
if (allowFreeTypeVariables == FreeTypeVariableBinding::Disallow &&
1351-
hasFreeTypeVariables())
1350+
if (!solverState->allowsFreeTypeVariables() && hasFreeTypeVariables())
13521351
return true;
13531352

1354-
auto solution = finalize(allowFreeTypeVariables);
1353+
auto solution = finalize();
13551354
if (TC.getLangOpts().DebugConstraintSolver) {
13561355
auto &log = getASTContext().TypeCheckerDebug->getStream();
13571356
log.indent(solverState->depth * 2)
@@ -1376,7 +1375,7 @@ bool ConstraintSystem::solveRec(SmallVectorImpl<Solution> &solutions,
13761375
// If we don't have more than one component, just solve the whole
13771376
// system.
13781377
if (numComponents < 2)
1379-
return solveSimplified(solutions, allowFreeTypeVariables);
1378+
return solveSimplified(solutions);
13801379

13811380
if (TC.Context.LangOpts.DebugConstraintSolver) {
13821381
auto &log = getASTContext().TypeCheckerDebug->getStream();
@@ -1487,8 +1486,7 @@ bool ConstraintSystem::solveRec(SmallVectorImpl<Solution> &solutions,
14871486
}
14881487

14891488
// Solve for this component. If it fails, we're done.
1490-
bool failed = bucket.solve(*this, partialSolutions[component],
1491-
allowFreeTypeVariables);
1489+
bool failed = bucket.solve(*this, partialSolutions[component]);
14921490

14931491
if (failed) {
14941492
if (TC.getLangOpts().DebugConstraintSolver) {
@@ -1553,7 +1551,7 @@ bool ConstraintSystem::solveRec(SmallVectorImpl<Solution> &solutions,
15531551
// skip it.
15541552
if (!worseThanBestSolution()) {
15551553
// Finalize this solution.
1556-
auto solution = finalize(allowFreeTypeVariables);
1554+
auto solution = finalize();
15571555
if (TC.getLangOpts().DebugConstraintSolver) {
15581556
auto &log = getASTContext().TypeCheckerDebug->getStream();
15591557
log.indent(solverState->depth * 2)
@@ -1777,8 +1775,7 @@ Constraint *ConstraintSystem::selectDisjunction() {
17771775
}
17781776

17791777
bool ConstraintSystem::solveForDisjunctionChoices(
1780-
Disjunction &disjunction, SmallVectorImpl<Solution> &solutions,
1781-
FreeTypeVariableBinding allowFreeTypeVariables) {
1778+
Disjunction &disjunction, SmallVectorImpl<Solution> &solutions) {
17821779
Optional<Score> bestNonGenericScore;
17831780
Optional<std::pair<DisjunctionChoice, Score>> lastSolvedChoice;
17841781

@@ -1835,7 +1832,7 @@ bool ConstraintSystem::solveForDisjunctionChoices(
18351832
}
18361833
}
18371834

1838-
if (auto score = currentChoice.solve(solutions, allowFreeTypeVariables)) {
1835+
if (auto score = currentChoice.solve(solutions)) {
18391836
if (!currentChoice.isGenericOperator() &&
18401837
currentChoice.isSymmetricOperator()) {
18411838
if (!bestNonGenericScore || score < bestNonGenericScore)
@@ -1855,8 +1852,7 @@ bool ConstraintSystem::solveForDisjunctionChoices(
18551852
}
18561853

18571854
bool ConstraintSystem::solveForDisjunction(
1858-
Constraint *disjunction, SmallVectorImpl<Solution> &solutions,
1859-
FreeTypeVariableBinding allowFreeTypeVariables) {
1855+
Constraint *disjunction, SmallVectorImpl<Solution> &solutions) {
18601856
assert(disjunction->getKind() == ConstraintKind::Disjunction);
18611857

18621858
// Remove this disjunction constraint from the list.
@@ -1915,8 +1911,7 @@ bool ConstraintSystem::solveForDisjunction(
19151911
auto choices = Disjunction(*this, disjunction->getNestedConstraints(),
19161912
locator, disjunction->isExplicitConversion());
19171913

1918-
auto noSolutions =
1919-
solveForDisjunctionChoices(choices, solutions, allowFreeTypeVariables);
1914+
auto noSolutions = solveForDisjunctionChoices(choices, solutions);
19201915

19211916
if (hasDisabledChoices) {
19221917
// Re-enable previously disabled overload choices.
@@ -1933,12 +1928,8 @@ bool ConstraintSystem::solveForDisjunction(
19331928
return noSolutions;
19341929
}
19351930

1936-
bool ConstraintSystem::solveSimplified(
1937-
SmallVectorImpl<Solution> &solutions,
1938-
FreeTypeVariableBinding allowFreeTypeVariables) {
1939-
1931+
bool ConstraintSystem::solveSimplified(SmallVectorImpl<Solution> &solutions) {
19401932
auto *disjunction = selectDisjunction();
1941-
19421933
auto bestBindings = determineBestBindings();
19431934

19441935
// If we've already explored a lot of potential solutions, bail.
@@ -1951,17 +1942,15 @@ bool ConstraintSystem::solveSimplified(
19511942
if (bestBindings && (!disjunction || (!bestBindings->InvolvesTypeVariables &&
19521943
!bestBindings->FullyBound))) {
19531944
return tryTypeVariableBindings(bestBindings->TypeVar,
1954-
bestBindings->Bindings, solutions,
1955-
allowFreeTypeVariables);
1945+
bestBindings->Bindings, solutions);
19561946
}
19571947

19581948
if (disjunction)
1959-
return solveForDisjunction(disjunction, solutions, allowFreeTypeVariables);
1949+
return solveForDisjunction(disjunction, solutions);
19601950

19611951
// If there are no disjunctions we can't solve this system unless we have
19621952
// free type variables and are allowing them in the solution.
1963-
if (allowFreeTypeVariables == FreeTypeVariableBinding::Disallow ||
1964-
!hasFreeTypeVariables())
1953+
if (!solverState->allowsFreeTypeVariables() || !hasFreeTypeVariables())
19651954
return true;
19661955

19671956
// If this solution is worse than the best solution we've seen so far,
@@ -1981,7 +1970,7 @@ bool ConstraintSystem::solveSimplified(
19811970
}
19821971
}
19831972

1984-
auto solution = finalize(allowFreeTypeVariables);
1973+
auto solution = finalize();
19851974
if (TC.getLangOpts().DebugConstraintSolver) {
19861975
auto &log = getASTContext().TypeCheckerDebug->getStream();
19871976
log.indent(solverState->depth * 2) << "(found solution)\n";
@@ -1991,15 +1980,13 @@ bool ConstraintSystem::solveSimplified(
19911980
return false;
19921981
}
19931982

1994-
Optional<Score>
1995-
DisjunctionChoice::solve(SmallVectorImpl<Solution> &solutions,
1996-
FreeTypeVariableBinding allowFreeTypeVariables) {
1983+
Optional<Score> DisjunctionChoice::solve(SmallVectorImpl<Solution> &solutions) {
19971984
CS->simplifyDisjunctionChoice(Choice);
19981985

19991986
if (ExplicitConversion)
20001987
propagateConversionInfo();
20011988

2002-
if (CS->solveRec(solutions, allowFreeTypeVariables))
1989+
if (CS->solveRec(solutions))
20031990
return None;
20041991

20051992
assert (!solutions.empty());

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,11 +2081,11 @@ bool ConstraintSystem::salvage(SmallVectorImpl<Solution> &viable, Expr *expr) {
20812081

20822082
{
20832083
// Set up solver state.
2084-
SolverState state(expr, *this);
2084+
SolverState state(expr, *this, FreeTypeVariableBinding::Disallow);
20852085
state.recordFixes = true;
20862086

20872087
// Solve the system.
2088-
solveRec(viable, FreeTypeVariableBinding::Disallow);
2088+
solveRec(viable);
20892089

20902090
// Check whether we have a best solution; this can happen if we found
20912091
// a series of fixes that worked.

lib/Sema/ConstraintSystem.h

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,14 +1139,17 @@ class ConstraintSystem {
11391139

11401140
/// \brief Describes the current solver state.
11411141
struct SolverState {
1142-
SolverState(Expr *const expr, ConstraintSystem &cs);
1142+
SolverState(Expr *const expr, ConstraintSystem &cs,
1143+
FreeTypeVariableBinding allowFreeTypeVariables);
11431144
~SolverState();
11441145

11451146
llvm::DenseMap<Expr *, unsigned> ExprWeights;
11461147

11471148
/// The constraint system.
11481149
ConstraintSystem &CS;
11491150

1151+
FreeTypeVariableBinding AllowFreeTypeVariables;
1152+
11501153
/// Old value of DebugConstraintSolver.
11511154
/// FIXME: Move the "debug constraint solver" bit into the constraint
11521155
/// system itself.
@@ -1288,6 +1291,12 @@ class ConstraintSystem {
12881291
generatedConstraints.erase(genStart, genEnd);
12891292
}
12901293

1294+
/// Check whether constraint system is allowed to form solutions
1295+
/// even with unbound type variables present.
1296+
bool allowsFreeTypeVariables() const {
1297+
return AllowFreeTypeVariables != FreeTypeVariableBinding::Disallow;
1298+
}
1299+
12911300
private:
12921301
/// The list of constraints that have been retired along the
12931302
/// current path, this list is used in LIFO fashion when constraints
@@ -1507,7 +1516,7 @@ class ConstraintSystem {
15071516
/// it.
15081517
///
15091518
/// \returns the solution.
1510-
Solution finalize(FreeTypeVariableBinding allowFreeTypeVariables);
1519+
Solution finalize();
15111520

15121521
/// \brief Apply the given solution to the current constraint system.
15131522
///
@@ -2950,8 +2959,7 @@ class ConstraintSystem {
29502959
bool
29512960
tryTypeVariableBindings(TypeVariableType *typeVar,
29522961
ArrayRef<ConstraintSystem::PotentialBinding> bindings,
2953-
SmallVectorImpl<Solution> &solutions,
2954-
FreeTypeVariableBinding allowFreeTypeVariables);
2962+
SmallVectorImpl<Solution> &solutions);
29552963

29562964
private:
29572965
/// \brief Add a constraint to the constraint system.
@@ -2967,31 +2975,24 @@ class ConstraintSystem {
29672975
///
29682976
/// \returns true if we failed to find any solutions, false otherwise.
29692977
bool solveForDisjunction(Constraint *disjunction,
2970-
SmallVectorImpl<Solution> &solutions,
2971-
FreeTypeVariableBinding allowFreeTypeVariables);
2978+
SmallVectorImpl<Solution> &solutions);
29722979

29732980
/// \brief Attempt to solve for some subset of the constraints in a
29742981
/// disjunction, skipping constraints that we decide do not
29752982
/// need to be solved for because they would not result in
29762983
/// the best solution to the constraint system.
29772984
///
29782985
/// \returns true if we failed to find any solutions, false otherwise.
2979-
bool
2980-
solveForDisjunctionChoices(Disjunction &disjunction,
2981-
SmallVectorImpl<Solution> &solutions,
2982-
FreeTypeVariableBinding allowFreeTypeVariables);
2986+
bool solveForDisjunctionChoices(Disjunction &disjunction,
2987+
SmallVectorImpl<Solution> &solutions);
29832988

29842989
/// \brief Solve the system of constraints after it has already been
29852990
/// simplified.
29862991
///
29872992
/// \param solutions The set of solutions to this system of constraints.
29882993
///
2989-
/// \param allowFreeTypeVariables How to bind free type variables in
2990-
/// the solution.
2991-
///
29922994
/// \returns true if an error occurred, false otherwise.
2993-
bool solveSimplified(SmallVectorImpl<Solution> &solutions,
2994-
FreeTypeVariableBinding allowFreeTypeVariables);
2995+
bool solveSimplified(SmallVectorImpl<Solution> &solutions);
29952996

29962997
/// \brief Find reduced domains of disjunction constraints for given
29972998
/// expression, this is achieved to solving individual sub-expressions
@@ -3075,12 +3076,8 @@ class ConstraintSystem {
30753076
///
30763077
/// \param solutions The set of solutions to this system of constraints.
30773078
///
3078-
/// \param allowFreeTypeVariables How to bind free type variables in
3079-
/// the solution.
3080-
///
30813079
/// \returns true if there are no solutions
3082-
bool solveRec(SmallVectorImpl<Solution> &solutions,
3083-
FreeTypeVariableBinding allowFreeTypeVariables);
3080+
bool solveRec(SmallVectorImpl<Solution> &solutions);
30843081

30853082
/// \brief Solve the system of constraints.
30863083
///
@@ -3402,8 +3399,7 @@ class DisjunctionChoice {
34023399
bool isSymmetricOperator() const;
34033400

34043401
/// \brief Apply given choice to the system and try to solve it.
3405-
Optional<Score> solve(SmallVectorImpl<Solution> &solutions,
3406-
FreeTypeVariableBinding allowFreeTypeVariables);
3402+
Optional<Score> solve(SmallVectorImpl<Solution> &solutions);
34073403

34083404
operator Constraint *() { return Choice; }
34093405

@@ -3536,8 +3532,7 @@ class Component {
35363532
Disjunctions.push_back(constraint);
35373533
}
35383534

3539-
bool solve(ConstraintSystem &cs, SmallVectorImpl<Solution> &solutions,
3540-
FreeTypeVariableBinding allowFreeTypeVariables) {
3535+
bool solve(ConstraintSystem &cs, SmallVectorImpl<Solution> &solutions) {
35413536
// Return constraints from the bucket back into circulation.
35423537
reinstateTo(cs.InactiveConstraints);
35433538

@@ -3550,7 +3545,7 @@ class Component {
35503545
llvm::SaveAndRestore<ConstraintSystem::SolverScope *>
35513546
partialSolutionScope(cs.solverState->PartialSolutionScope, &scope);
35523547

3553-
failed = cs.solveSimplified(solutions, allowFreeTypeVariables);
3548+
failed = cs.solveSimplified(solutions);
35543549
}
35553550

35563551
// Put the constraints back into their original bucket.

0 commit comments

Comments
 (0)