Skip to content

Commit 08afa13

Browse files
committed
[Constraint graph] Fix gathering of one-way constraints.
We only care about gathering a one-way constraint if (1) the left-hand side is in the set of type variables we care about now, and (2) the type variable we started from is in the right-hand side.
1 parent 360800d commit 08afa13

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

lib/Sema/ConstraintGraph.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -378,19 +378,37 @@ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
378378
llvm::function_ref<bool(Constraint *)> acceptConstraintFn) {
379379
llvm::TinyPtrVector<Constraint *> constraints;
380380

381+
// Local function to test whether the given type variable is in the current
382+
// interest set for the solver.
383+
SmallPtrSet<TypeVariableType *, 4> interestingTypeVars;
384+
auto isInterestingTypeVar = [&](TypeVariableType *typeVar) {
385+
if (interestingTypeVars.empty()) {
386+
interestingTypeVars.insert(CS.TypeVariables.begin(),
387+
CS.TypeVariables.end());
388+
}
389+
390+
return interestingTypeVars.count(typeVar) > 0;
391+
};
392+
381393
// Whether we should consider this constraint at all.
382-
auto &reprNode = (*this)[CS.getRepresentative(typeVar)];
383-
auto equivClass = reprNode.getEquivalenceClass();
394+
auto rep = CS.getRepresentative(typeVar);
384395
auto shouldConsiderConstraint = [&](Constraint *constraint) {
385396
// For a one-way constraint, only consider it when the type variable
386-
// is on the left-hand side of the the binding. Otherwise, it is not
387-
// relevant.
397+
// is on the right-hand side of the the binding, and the left-hand side of
398+
// the binding is one of the type variables currently under consideration.
388399
if (constraint->getKind() == ConstraintKind::OneWayBind) {
389400
auto lhsTypeVar =
390401
constraint->getFirstType()->castTo<TypeVariableType>();
391-
if (std::find(equivClass.begin(), equivClass.end(), lhsTypeVar)
392-
== equivClass.end())
402+
if (!isInterestingTypeVar(lhsTypeVar))
393403
return false;
404+
405+
SmallVector<TypeVariableType *, 2> rhsTypeVars;
406+
constraint->getSecondType()->getTypeVariables(rhsTypeVars);
407+
for (auto rhsTypeVar : rhsTypeVars) {
408+
if (CS.getRepresentative(rhsTypeVar) == rep)
409+
return true;
410+
}
411+
return false;
394412
}
395413

396414
return true;
@@ -421,6 +439,8 @@ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
421439
}
422440
};
423441

442+
auto &reprNode = (*this)[CS.getRepresentative(typeVar)];
443+
auto equivClass = reprNode.getEquivalenceClass();
424444
for (auto typeVar : equivClass) {
425445
auto &node = (*this)[typeVar];
426446
for (auto constraint : node.getConstraints()) {

0 commit comments

Comments
 (0)