Skip to content

Commit b9e08b2

Browse files
committed
[ConstraintSystem] Allow the solver to find other solutions after
successfully finding a solution by favoring operators already bound elsewhere. Favoring existing operator bindings often lets the solver find a solution fast, but it's not necessarily the best solution.
1 parent 91291c7 commit b9e08b2

File tree

3 files changed

+0
-97
lines changed

3 files changed

+0
-97
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2467,16 +2467,6 @@ class ConstraintSystem {
24672467
favoredConstraints.push_back(constraint);
24682468
}
24692469

2470-
/// Whether or not the given constraint is only favored during this scope.
2471-
bool isTemporarilyFavored(Constraint *constraint) {
2472-
assert(constraint->isFavored());
2473-
2474-
for (auto test : favoredConstraints)
2475-
if (test == constraint)
2476-
return true;
2477-
return false;
2478-
}
2479-
24802470
private:
24812471
/// The list of constraints that have been retired along the
24822472
/// current path, this list is used in LIFO fashion when constraints

lib/Sema/CSStep.cpp

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -614,25 +614,6 @@ bool DisjunctionStep::shortCircuitDisjunctionAt(
614614
Constraint *currentChoice, Constraint *lastSuccessfulChoice) const {
615615
auto &ctx = CS.getASTContext();
616616

617-
// If the successfully applied constraint is favored, we'll consider that to
618-
// be the "best". If it was only temporarily favored because it matched other
619-
// operator bindings, we can even short-circuit other favored constraints.
620-
if (lastSuccessfulChoice->isFavored() &&
621-
(!currentChoice->isFavored() ||
622-
(CS.solverState->isTemporarilyFavored(lastSuccessfulChoice) &&
623-
!CS.solverState->isTemporarilyFavored(currentChoice)))) {
624-
#if !defined(NDEBUG)
625-
if (lastSuccessfulChoice->getKind() == ConstraintKind::BindOverload) {
626-
auto overloadChoice = lastSuccessfulChoice->getOverloadChoice();
627-
assert((!overloadChoice.isDecl() ||
628-
!overloadChoice.getDecl()->getAttrs().isUnavailable(ctx)) &&
629-
"Unavailable decl should not be favored!");
630-
}
631-
#endif
632-
633-
return true;
634-
}
635-
636617
// Anything without a fix is better than anything with a fix.
637618
if (currentChoice->getFix() && !lastSuccessfulChoice->getFix())
638619
return true;
@@ -670,36 +651,6 @@ bool DisjunctionStep::shortCircuitDisjunctionAt(
670651
if (isSIMDOperator(currentChoice->getOverloadChoice().getDecl()) &&
671652
!isSIMDOperator(lastSuccessfulChoice->getOverloadChoice().getDecl()))
672653
return true;
673-
674-
// Otherwise if we have an existing solution, bind tyvars bound to the same
675-
// decl in the solution to the choice tyvar. We can continue finding more
676-
// solutions, but all the instances of the operator that chose the same
677-
// overload as this successful choice will be bound togeter.
678-
if (Solutions.size()) {
679-
auto lastTyvar =
680-
lastSuccessfulChoice->getFirstType()->getAs<TypeVariableType>();
681-
auto lastRep = CS.getRepresentative(lastTyvar);
682-
683-
for (auto overload : Solutions[0].overloadChoices) {
684-
auto overloadChoice = overload.getSecond().choice;
685-
if (!overloadChoice.isDecl() ||
686-
overloadChoice.getDecl() !=
687-
lastSuccessfulChoice->getOverloadChoice().getDecl())
688-
continue;
689-
690-
auto choiceTyvar =
691-
CS.getType(simplifyLocatorToAnchor(overload.getFirst()))
692-
->getAs<TypeVariableType>();
693-
if (!choiceTyvar)
694-
continue;
695-
696-
auto rep = CS.getRepresentative(choiceTyvar);
697-
if (lastRep != rep) {
698-
CS.mergeEquivalenceClasses(rep, lastRep, /*updateWorkList=*/false);
699-
lastRep = CS.getRepresentative(lastRep);
700-
}
701-
}
702-
}
703654
}
704655
return false;
705656
}

lib/Sema/CSStep.h

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,6 @@ class DisjunctionStep final : public BindingStep<DisjunctionChoiceProducer> {
649649
: BindingStep(cs, {cs, disjunction}, solutions), Disjunction(disjunction),
650650
AfterDisjunction(erase(disjunction)) {
651651
assert(Disjunction->getKind() == ConstraintKind::Disjunction);
652-
pruneOverloadSet(Disjunction);
653652
++cs.solverState->NumDisjunctions;
654653
}
655654

@@ -697,43 +696,6 @@ class DisjunctionStep final : public BindingStep<DisjunctionChoiceProducer> {
697696
/// simplified further, false otherwise.
698697
bool attempt(const DisjunctionChoice &choice) override;
699698

700-
// Check if selected disjunction has a representative
701-
// this might happen when there are multiple binary operators
702-
// chained together. If so, disable choices which differ
703-
// from currently selected representative.
704-
void pruneOverloadSet(Constraint *disjunction) {
705-
auto *choice = disjunction->getNestedConstraints().front();
706-
auto *typeVar = choice->getFirstType()->getAs<TypeVariableType>();
707-
if (!typeVar)
708-
return;
709-
710-
auto *repr = typeVar->getImpl().getRepresentative(nullptr);
711-
if (!repr || repr == typeVar)
712-
return;
713-
714-
for (auto overload : CS.getResolvedOverloads()) {
715-
auto resolved = overload.second;
716-
if (!resolved.boundType->isEqual(repr))
717-
continue;
718-
719-
auto &representative = resolved.choice;
720-
if (!representative.isDecl())
721-
return;
722-
723-
// Disable all of the overload choices which are different from
724-
// the one which is currently picked for representative.
725-
for (auto *constraint : disjunction->getNestedConstraints()) {
726-
auto choice = constraint->getOverloadChoice();
727-
if (!choice.isDecl() || choice.getDecl() == representative.getDecl())
728-
continue;
729-
730-
constraint->setDisabled();
731-
DisabledChoices.push_back(constraint);
732-
}
733-
break;
734-
}
735-
};
736-
737699
// Figure out which of the solutions has the smallest score.
738700
static Optional<Score> getBestScore(SmallVectorImpl<Solution> &solutions) {
739701
assert(!solutions.empty());

0 commit comments

Comments
 (0)