@@ -556,22 +556,25 @@ void ConstraintGraph::retractBindings(TypeVariableType *typeVar,
556
556
// /
557
557
// / \param cg The constraint graph.
558
558
// / \param typeVar The type variable we're searching from.
559
- // / \param visitConstraint Called before considering a constraint.
559
+ // / \param preVisitNode Called before traversing a node. Must return \c
560
+ // / false when the node has already been visited.
561
+ // / \param visitConstraint Called before considering a constraint. If it
562
+ // / returns \c false, that constraint will be skipped.
560
563
// / \param visitedConstraints Set of already-visited constraints, used
561
564
// / internally to avoid duplicated work.
562
565
static void depthFirstSearch (
563
566
ConstraintGraph &cg,
564
567
TypeVariableType *typeVar,
565
- llvm::function_ref<void (Constraint *)> visitConstraint ,
566
- llvm::SmallPtrSet<TypeVariableType *, 4> &typeVars ,
568
+ llvm::function_ref<bool (TypeVariableType *)> preVisitNode ,
569
+ llvm::function_ref<bool(Constraint *)> visitConstraint ,
567
570
llvm::SmallPtrSet<Constraint *, 8> &visitedConstraints) {
568
571
// If we're not looking at this type variable right now because we're
569
572
// solving a conjunction element, don't consider its adjacencies.
570
573
if (!cg.getConstraintSystem ().isActiveTypeVariable (typeVar))
571
574
return ;
572
575
573
576
// Visit this node. If we've already seen it, bail out.
574
- if (!typeVars. insert (typeVar). second )
577
+ if (!preVisitNode (typeVar))
575
578
return ;
576
579
577
580
// Local function to visit adjacent type variables.
@@ -581,18 +584,21 @@ static void depthFirstSearch(
581
584
continue ;
582
585
583
586
// Recurse into this node.
584
- depthFirstSearch (cg, adj, visitConstraint, typeVars, visitedConstraints);
587
+ depthFirstSearch (cg, adj, preVisitNode, visitConstraint,
588
+ visitedConstraints);
585
589
}
586
590
};
587
591
588
- // Walk all of the constraints associated with this node.
592
+ // Walk all of the constraints associated with this node to find related
593
+ // nodes.
589
594
auto &node = cg[typeVar];
590
595
for (auto constraint : node.getConstraints ()) {
591
596
// If we've already seen this constraint, skip it.
592
597
if (!visitedConstraints.insert (constraint).second )
593
598
continue ;
594
599
595
- visitConstraint (constraint);
600
+ if (visitConstraint (constraint))
601
+ visitAdjacencies (constraint->getTypeVariables ());
596
602
}
597
603
598
604
// Visit all of the other nodes in the equivalence class.
@@ -623,11 +629,17 @@ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
623
629
// constraints involving both it and its fixed bindings.
624
630
depthFirstSearch (
625
631
*this , typeVar,
632
+ [&](TypeVariableType *typeVar) {
633
+ return typeVars.insert (typeVar).second ;
634
+ },
626
635
[&](Constraint *constraint) {
627
636
if (acceptConstraintFn (constraint))
628
637
constraints.push_back (constraint);
638
+
639
+ // Don't recurse into the constraint's type variables.
640
+ return false ;
629
641
},
630
- typeVars, visitedConstraints);
642
+ visitedConstraints);
631
643
return constraints;
632
644
}
633
645
0 commit comments