Skip to content

Commit 71c2c1e

Browse files
authored
Merge pull request swiftlang#10484 from xedin/rdar-32726044
[ConstraintSolver] Use a flag to prevent solver from removing possible solutions
2 parents 18078c1 + 6231f85 commit 71c2c1e

File tree

4 files changed

+60
-20
lines changed

4 files changed

+60
-20
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ void ConstraintSystem::increaseScore(ScoreKind kind, unsigned value) {
8585
}
8686

8787
bool ConstraintSystem::worseThanBestSolution() const {
88+
if (retainAllSolutions())
89+
return false;
90+
8891
if (!solverState || !solverState->BestScore ||
8992
CurrentScore <= *solverState->BestScore)
9093
return false;

lib/Sema/CSSolver.cpp

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Solution ConstraintSystem::finalize(
110110
Solution solution(*this, CurrentScore);
111111

112112
// Update the best score we've seen so far.
113-
if (solverState) {
113+
if (solverState && !retainAllSolutions()) {
114114
assert(!solverState->BestScore || CurrentScore <= *solverState->BestScore);
115115
solverState->BestScore = CurrentScore;
116116
}
@@ -1499,7 +1499,8 @@ bool ConstraintSystem::Candidate::solve(
14991499
};
15001500

15011501
// Allocate new constraint system for sub-expression.
1502-
ConstraintSystem cs(TC, DC, None);
1502+
ConstraintSystem cs(TC, DC,
1503+
ConstraintSystemFlags::ReturnAllDiscoveredSolutions);
15031504

15041505
// Cleanup after constraint system generation/solving,
15051506
// because it would assign types to expressions, which
@@ -2070,17 +2071,11 @@ bool ConstraintSystem::solve(SmallVectorImpl<Solution> &solutions,
20702071
// Solve the system.
20712072
solveRec(solutions, allowFreeTypeVariables);
20722073

2073-
// If there is more than one viable system, attempt to pick the best
2074-
// solution.
2075-
auto size = solutions.size();
2076-
if (size > 1 &&
2077-
!Options.contains(ConstraintSystemFlags::ReturnAllDiscoveredSolutions)) {
2078-
if (auto best = findBestSolution(solutions, /*minimize=*/false)) {
2079-
if (*best != 0)
2080-
solutions[0] = std::move(solutions[*best]);
2081-
solutions.erase(solutions.begin() + 1, solutions.end());
2082-
}
2083-
}
2074+
// Filter deduced solutions, try to figure out if there is
2075+
// a single best solution to use, if not explicitly disabled
2076+
// by constraint system options.
2077+
if (!retainAllSolutions())
2078+
filterSolutions(solutions);
20842079

20852080
// We fail if there is no solution.
20862081
return solutions.empty();
@@ -2293,11 +2288,8 @@ bool ConstraintSystem::solveRec(SmallVectorImpl<Solution> &solutions,
22932288
auto &solutions = partialSolutions[component];
22942289
// If there's a single best solution, keep only that one.
22952290
// Otherwise, the set of solutions will at least have been minimized.
2296-
if (auto best = findBestSolution(solutions, /*minimize=*/true)) {
2297-
if (*best > 0)
2298-
solutions[0] = std::move(solutions[*best]);
2299-
solutions.erase(solutions.begin() + 1, solutions.end());
2300-
}
2291+
if (!retainAllSolutions())
2292+
filterSolutions(solutions, /*minimize=*/true);
23012293
}
23022294

23032295
// Produce all combinations of partial solutions.

lib/Sema/ConstraintSystem.h

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,13 @@ class ConstraintSystem {
14131413
bool hasFreeTypeVariables();
14141414

14151415
private:
1416+
/// \brief Indicates if the constraint system should retain all of the
1417+
/// solutions it has deduced regardless of their score.
1418+
bool retainAllSolutions() const {
1419+
return Options.contains(
1420+
ConstraintSystemFlags::ReturnAllDiscoveredSolutions);
1421+
}
1422+
14161423
/// \brief Finalize this constraint system; we're done attempting to solve
14171424
/// it.
14181425
///
@@ -1434,8 +1441,28 @@ class ConstraintSystem {
14341441
/// diagnostic for it and returning true. If the fixit hint turned out to be
14351442
/// bogus, this returns false and doesn't emit anything.
14361443
bool applySolutionFix(Expr *expr, const Solution &solution, unsigned fixNo);
1437-
1438-
1444+
1445+
/// \brief If there is more than one viable solution,
1446+
/// attempt to pick the best solution and remove all of the rest.
1447+
///
1448+
/// \param solutions The set of solutions to filter.
1449+
///
1450+
/// \param minimize The flag which idicates if the
1451+
/// set of solutions should be filtered even if there is
1452+
/// no single best solution, see `findBestSolution` for
1453+
/// more details.
1454+
void filterSolutions(SmallVectorImpl<Solution> &solutions,
1455+
bool minimize = false) {
1456+
if (solutions.size() < 2)
1457+
return;
1458+
1459+
if (auto best = findBestSolution(solutions, minimize)) {
1460+
if (*best != 0)
1461+
solutions[0] = std::move(solutions[*best]);
1462+
solutions.erase(solutions.begin() + 1, solutions.end());
1463+
}
1464+
}
1465+
14391466
/// \brief Restore the type variable bindings to what they were before
14401467
/// we attempted to solve this constraint system.
14411468
///

test/Constraints/diagnostics.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,3 +983,21 @@ let _: KeyPath<R32101765, Float> = \R32101765.prop32101765.unknown
983983
for var i in 0..<10 { // expected-warning {{variable 'i' was never mutated; consider changing to 'let' constant}} {{5-9=}}
984984
_ = i + 1
985985
}
986+
987+
// rdar://problem/32726044 - shrink reduced domains too far
988+
989+
public protocol P_32726044 {}
990+
991+
extension Int: P_32726044 {}
992+
extension Float: P_32726044 {}
993+
994+
public func *(lhs: P_32726044, rhs: P_32726044) -> Double {
995+
fatalError()
996+
}
997+
998+
func rdar32726044() -> Float {
999+
var f: Float = 0
1000+
f = Float(1) * 100 // Ok
1001+
let _: Float = Float(42) + 0 // Ok
1002+
return f
1003+
}

0 commit comments

Comments
 (0)