mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ConstraintSystem] Remove an attempted optimization that we've not
seen benefit from. This was added at one point after the observation that it may in theory allow us to solve constraint systems more quickly, but there wasn't really a motivating test case and we do not know of any real code that it helps with. We currently have a problem in the solver in that we are both short-circuiting evaluation of constraints systems, *and* do not have a stable order that we visit disjunctions. These in combination can result in inconsistent and unpredictable results, so I am moving to enforce a stable order for visiting disjunctions, and that requires this code to be removed.
This commit is contained in:
@@ -1805,91 +1805,10 @@ static bool shouldSkipDisjunctionChoice(ConstraintSystem &cs,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to find a disjunction of bind constraints where all options
|
||||
// in the disjunction are binding the same type variable.
|
||||
//
|
||||
// Prefer disjunctions where the bound type variable is also the
|
||||
// right-hand side of a conversion constraint, since having a concrete
|
||||
// type that we're converting to can make it possible to split the
|
||||
// constraint system into multiple ones.
|
||||
static Constraint *selectBestBindingDisjunction(
|
||||
ConstraintSystem &cs, SmallVectorImpl<Constraint *> &disjunctions) {
|
||||
|
||||
if (disjunctions.empty())
|
||||
return nullptr;
|
||||
|
||||
// Collect any disjunctions that simply attempt bindings for a
|
||||
// type variable.
|
||||
SmallVector<Constraint *, 8> bindingDisjunctions;
|
||||
for (auto *disjunction : disjunctions) {
|
||||
llvm::Optional<TypeVariableType *> commonTypeVariable;
|
||||
if (llvm::all_of(
|
||||
disjunction->getNestedConstraints(),
|
||||
[&](Constraint *bindingConstraint) {
|
||||
if (bindingConstraint->getKind() != ConstraintKind::Bind)
|
||||
return false;
|
||||
|
||||
auto *tv =
|
||||
bindingConstraint->getFirstType()->getAs<TypeVariableType>();
|
||||
// Only do this for simple type variable bindings, not for
|
||||
// bindings like: ($T1) -> $T2 bind String -> Int
|
||||
if (!tv)
|
||||
return false;
|
||||
|
||||
if (!commonTypeVariable.hasValue())
|
||||
commonTypeVariable = tv;
|
||||
|
||||
if (commonTypeVariable.getValue() != tv)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
})) {
|
||||
bindingDisjunctions.push_back(disjunction);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto *disjunction : bindingDisjunctions) {
|
||||
auto nested = disjunction->getNestedConstraints();
|
||||
assert(!nested.empty());
|
||||
auto *tv = cs.simplifyType(nested[0]->getFirstType())
|
||||
->getRValueType()
|
||||
->getAs<TypeVariableType>();
|
||||
assert(tv);
|
||||
|
||||
SmallVector<Constraint *, 8> constraints;
|
||||
cs.getConstraintGraph().gatherConstraints(
|
||||
tv, constraints, ConstraintGraph::GatheringKind::EquivalenceClass);
|
||||
|
||||
for (auto *constraint : constraints) {
|
||||
if (constraint->getKind() != ConstraintKind::Conversion)
|
||||
continue;
|
||||
|
||||
auto toType =
|
||||
cs.simplifyType(constraint->getSecondType())->getRValueType();
|
||||
auto *toTV = toType->getAs<TypeVariableType>();
|
||||
if (tv != toTV)
|
||||
continue;
|
||||
|
||||
return disjunction;
|
||||
}
|
||||
}
|
||||
|
||||
// If we had any binding disjunctions, return the first of
|
||||
// those. These ensure that we attempt to bind types earlier than
|
||||
// trying the elements of other disjunctions, which can often mean
|
||||
// we fail faster.
|
||||
if (!bindingDisjunctions.empty())
|
||||
return bindingDisjunctions[0];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Constraint *ConstraintSystem::selectDisjunction() {
|
||||
SmallVector<Constraint *, 4> disjunctions;
|
||||
|
||||
collectDisjunctions(disjunctions);
|
||||
if (auto *disjunction = selectBestBindingDisjunction(*this, disjunctions))
|
||||
return disjunction;
|
||||
|
||||
// Pick the disjunction with the lowest disjunction number in order
|
||||
// to solve them in the order they were created (which should be
|
||||
|
||||
Reference in New Issue
Block a user