@@ -556,22 +556,25 @@ void ConstraintGraph::retractBindings(TypeVariableType *typeVar,
556556// /
557557// / \param cg The constraint graph.
558558// / \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.
560563// / \param visitedConstraints Set of already-visited constraints, used
561564// / internally to avoid duplicated work.
562565static void depthFirstSearch (
563566 ConstraintGraph &cg,
564567 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 ,
567570 llvm::SmallPtrSet<Constraint *, 8> &visitedConstraints) {
568571 // If we're not looking at this type variable right now because we're
569572 // solving a conjunction element, don't consider its adjacencies.
570573 if (!cg.getConstraintSystem ().isActiveTypeVariable (typeVar))
571574 return ;
572575
573576 // Visit this node. If we've already seen it, bail out.
574- if (!typeVars. insert (typeVar). second )
577+ if (!preVisitNode (typeVar))
575578 return ;
576579
577580 // Local function to visit adjacent type variables.
@@ -581,18 +584,21 @@ static void depthFirstSearch(
581584 continue ;
582585
583586 // Recurse into this node.
584- depthFirstSearch (cg, adj, visitConstraint, typeVars, visitedConstraints);
587+ depthFirstSearch (cg, adj, preVisitNode, visitConstraint,
588+ visitedConstraints);
585589 }
586590 };
587591
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.
589594 auto &node = cg[typeVar];
590595 for (auto constraint : node.getConstraints ()) {
591596 // If we've already seen this constraint, skip it.
592597 if (!visitedConstraints.insert (constraint).second )
593598 continue ;
594599
595- visitConstraint (constraint);
600+ if (visitConstraint (constraint))
601+ visitAdjacencies (constraint->getTypeVariables ());
596602 }
597603
598604 // Visit all of the other nodes in the equivalence class.
@@ -623,11 +629,17 @@ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
623629 // constraints involving both it and its fixed bindings.
624630 depthFirstSearch (
625631 *this , typeVar,
632+ [&](TypeVariableType *typeVar) {
633+ return typeVars.insert (typeVar).second ;
634+ },
626635 [&](Constraint *constraint) {
627636 if (acceptConstraintFn (constraint))
628637 constraints.push_back (constraint);
638+
639+ // Don't recurse into the constraint's type variables.
640+ return false ;
629641 },
630- typeVars, visitedConstraints);
642+ visitedConstraints);
631643 return constraints;
632644 }
633645
0 commit comments