mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[CSStep] Conjunction: Propagate fix and hole scores to outer solution
While producing a combined solution, let's reflect the number of fixes and holes discovered in the conjunction, that way it would be possible to filter solutions and keep track of the fact that there were issues in the conjunction.
This commit is contained in:
committed by
Pavel Yaskevich
parent
dfadee3731
commit
4debf30f58
@@ -942,13 +942,10 @@ StepResult ConjunctionStep::resume(bool prevFailed) {
|
||||
// and scoring information.
|
||||
Snapshot.reset();
|
||||
|
||||
// Restore original scores of outer context before
|
||||
// trying to produce a combined solution.
|
||||
restoreOriginalScores();
|
||||
|
||||
// Apply all of the information deduced from the
|
||||
// conjunction (up to the point of ambiguity)
|
||||
// back to the outer context and form a joined solution.
|
||||
unsigned numSolutions = 0;
|
||||
for (auto &solution : Solutions) {
|
||||
ConstraintSystem::SolverScope scope(CS);
|
||||
|
||||
@@ -958,34 +955,47 @@ StepResult ConjunctionStep::resume(bool prevFailed) {
|
||||
// of the constraint system, so they have to be
|
||||
// restored right afterwards because score of the
|
||||
// element does contribute to the overall score.
|
||||
restoreOriginalScores();
|
||||
restoreBestScore();
|
||||
restoreCurrentScore(solution.getFixedScore());
|
||||
|
||||
// Transform all of the unbound outer variables into
|
||||
// placeholders since we are not going to solve for
|
||||
// each ambguous solution.
|
||||
for (auto *typeVar : CS.getTypeVariables()) {
|
||||
if (!typeVar->getImpl().hasRepresentativeOrFixed()) {
|
||||
CS.assignFixedType(
|
||||
typeVar, PlaceholderType::get(CS.getASTContext(), typeVar));
|
||||
{
|
||||
unsigned numHoles = 0;
|
||||
for (auto *typeVar : CS.getTypeVariables()) {
|
||||
if (!typeVar->getImpl().hasRepresentativeOrFixed()) {
|
||||
CS.assignFixedType(
|
||||
typeVar, PlaceholderType::get(CS.getASTContext(), typeVar));
|
||||
++numHoles;
|
||||
}
|
||||
}
|
||||
CS.increaseScore(SK_Hole, numHoles);
|
||||
}
|
||||
|
||||
if (CS.worseThanBestSolution())
|
||||
continue;
|
||||
|
||||
// Note that `worseThanBestSolution` isn't checked
|
||||
// here because `Solutions` were pre-filtered, and
|
||||
// outer score is the same for all of them.
|
||||
OuterSolutions.push_back(CS.finalize());
|
||||
++numSolutions;
|
||||
}
|
||||
|
||||
return done(/*isSuccess=*/true);
|
||||
return done(/*isSuccess=*/numSolutions > 0);
|
||||
}
|
||||
|
||||
auto solution = Solutions.pop_back_val();
|
||||
auto score = solution.getFixedScore();
|
||||
|
||||
// Restore outer type variables and prepare to solve
|
||||
// constraints associated with outer context together
|
||||
// with information deduced from the conjunction.
|
||||
Snapshot->setupOuterContext(Solutions.pop_back_val());
|
||||
Snapshot->setupOuterContext(std::move(solution));
|
||||
|
||||
// Pretend that conjunction never happened.
|
||||
restoreOuterState();
|
||||
restoreOuterState(score);
|
||||
|
||||
// Now that all of the information from the conjunction has
|
||||
// been applied, let's attempt to solve the outer scope.
|
||||
@@ -997,10 +1007,11 @@ StepResult ConjunctionStep::resume(bool prevFailed) {
|
||||
return take(prevFailed);
|
||||
}
|
||||
|
||||
void ConjunctionStep::restoreOuterState() const {
|
||||
void ConjunctionStep::restoreOuterState(const Score &solutionScore) const {
|
||||
// Restore best/current score, since upcoming step is going to
|
||||
// work with outer scope in relation to the conjunction.
|
||||
restoreOriginalScores();
|
||||
restoreBestScore();
|
||||
restoreCurrentScore(solutionScore);
|
||||
|
||||
// Active all of the previously out-of-scope constraints
|
||||
// because conjunction can propagate type information up
|
||||
|
||||
Reference in New Issue
Block a user