Skip to content

Commit b12bd4e

Browse files
authored
Merge pull request swiftlang#30307 from hborla/merge-partial-solutions-too-complex
[ConstraintSystem] Respect the constraint solver performance thresholds,
2 parents 1046516 + c1c6a88 commit b12bd4e

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

lib/Sema/CSStep.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ bool SplitterStep::mergePartialSolutions() const {
220220
ArrayRef<unsigned> counts = countsVec;
221221
SmallVector<unsigned, 2> indices(numComponents, 0);
222222
bool anySolutions = false;
223+
size_t solutionMemory = 0;
223224
do {
224225
// Create a new solver scope in which we apply all of the relevant partial
225226
// solutions.
@@ -236,13 +237,20 @@ bool SplitterStep::mergePartialSolutions() const {
236237
if (!CS.worseThanBestSolution()) {
237238
// Finalize this solution.
238239
auto solution = CS.finalize();
240+
solutionMemory += solution.getTotalMemory();
239241
if (isDebugMode())
240242
getDebugLogger() << "(composed solution " << CS.CurrentScore << ")\n";
241243

242244
// Save this solution.
243245
Solutions.push_back(std::move(solution));
244246
anySolutions = true;
245247
}
248+
249+
// Since merging partial solutions can go exponential, make sure we didn't
250+
// pass the "too complex" thresholds including allocated memory and time.
251+
if (CS.getExpressionTooComplex(solutionMemory))
252+
return false;
253+
246254
} while (nextCombination(counts, indices));
247255

248256
return anySolutions;

lib/Sema/ConstraintSystem.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4469,14 +4469,11 @@ class ConstraintSystem {
44694469
/// Determine if we've already explored too many paths in an
44704470
/// attempt to solve this expression.
44714471
bool isExpressionAlreadyTooComplex = false;
4472-
bool getExpressionTooComplex(SmallVectorImpl<Solution> const &solutions) {
4472+
bool getExpressionTooComplex(size_t solutionMemory) {
44734473
if (isExpressionAlreadyTooComplex)
44744474
return true;
44754475

4476-
auto used = getASTContext().getSolverMemory();
4477-
for (auto const& s : solutions) {
4478-
used += s.getTotalMemory();
4479-
}
4476+
auto used = getASTContext().getSolverMemory() + solutionMemory;
44804477
MaxMemory = std::max(used, MaxMemory);
44814478
auto threshold = getASTContext().TypeCheckerOpts.SolverMemoryThreshold;
44824479
if (MaxMemory > threshold) {
@@ -4503,6 +4500,14 @@ class ConstraintSystem {
45034500
return false;
45044501
}
45054502

4503+
bool getExpressionTooComplex(SmallVectorImpl<Solution> const &solutions) {
4504+
size_t solutionMemory = 0;
4505+
for (auto const& s : solutions) {
4506+
solutionMemory += s.getTotalMemory();
4507+
}
4508+
return getExpressionTooComplex(solutionMemory);
4509+
}
4510+
45064511
// Utility class that can collect information about the type of an
45074512
// argument in an apply.
45084513
//
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1
2+
// REQUIRES: tools-release,no_asan
3+
4+
class Color {
5+
init(hue: Double, saturation: Double, brightness: Double, alpha: Double) {}
6+
init(red: Double, green: Double, blue: Double, alpha: Double) {}
7+
}
8+
9+
// expected-error@+1 {{reasonable time}}
10+
let _: [Color] = [
11+
Color(r: 3, g: 72, b: 14, a: 48),
12+
Color(r: 0, g: 240, b: 64, a: 77),
13+
Color(r: 0, g: 255, b: 0, a: 160),
14+
Color(r: 0, g: 168, b: 0, a: 255),
15+
Color(r: 0, g: 140, b: 0, a: 255),
16+
Color(r: 0, g: 112, b: 0, a: 255),
17+
Color(r: 255, g: 255, b: 0, a: 255),
18+
Color(r: 184, g: 184, b: 0, a: 255),
19+
Color(r: 224, g: 112, b: 0, a: 255),
20+
Color(r: 255, g: 0, b: 0, a: 255),
21+
Color(r: 184, g: 0, b: 0, a: 255),
22+
Color(r: 112, g: 0, b: 0, a: 255),
23+
Color(r: 255, g: 0, b: 255, a: 255),
24+
Color(r: 255, g: 0, b: 255, a: 255),
25+
Color(r: 255, g: 0, b: 255, a: 255),
26+
Color(r: 0, g: 0, b: 0, a: 0),
27+
]

0 commit comments

Comments
 (0)