@@ -552,11 +552,18 @@ void ConstraintGraph::retractBindings(TypeVariableType *typeVar,
552
552
553
553
#pragma mark Algorithms
554
554
555
+ // / Perform a depth-first search.
556
+ // /
557
+ // / \param cg The constraint graph.
558
+ // / \param typeVar The type variable we're searching from.
559
+ // / \param visitConstraint Called before considering a constraint.
560
+ // / \param visitedConstraints Set of already-visited constraints, used
561
+ // / internally to avoid duplicated work.
555
562
static void depthFirstSearch (
556
563
ConstraintGraph &cg,
557
564
TypeVariableType *typeVar,
565
+ llvm::function_ref<void (Constraint *)> visitConstraint,
558
566
llvm::SmallPtrSet<TypeVariableType *, 4> &typeVars,
559
- llvm::TinyPtrVector<Constraint *> &constraints,
560
567
llvm::SmallPtrSet<Constraint *, 8> &visitedConstraints) {
561
568
// If we're not looking at this type variable right now because we're
562
569
// solving a conjunction element, don't consider its adjacencies.
@@ -570,8 +577,11 @@ static void depthFirstSearch(
570
577
// Local function to visit adjacent type variables.
571
578
auto visitAdjacencies = [&](ArrayRef<TypeVariableType *> adjTypeVars) {
572
579
for (auto adj : adjTypeVars) {
573
- if (adj != typeVar)
574
- depthFirstSearch (cg, adj, typeVars, constraints, visitedConstraints);
580
+ if (adj == typeVar)
581
+ continue ;
582
+
583
+ // Recurse into this node.
584
+ depthFirstSearch (cg, adj, visitConstraint, typeVars, visitedConstraints);
575
585
}
576
586
};
577
587
@@ -582,7 +592,7 @@ static void depthFirstSearch(
582
592
if (!visitedConstraints.insert (constraint).second )
583
593
continue ;
584
594
585
- constraints. push_back (constraint);
595
+ visitConstraint (constraint);
586
596
}
587
597
588
598
// Visit all of the other nodes in the equivalence class.
@@ -601,22 +611,28 @@ static void depthFirstSearch(
601
611
visitAdjacencies (node.getReferencedVars ());
602
612
}
603
613
604
- llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherAllConstraints (
605
- TypeVariableType *typeVar) {
614
+ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints (
615
+ TypeVariableType *typeVar, GatheringKind kind,
616
+ llvm::function_ref<bool (Constraint *)> acceptConstraintFn) {
606
617
llvm::TinyPtrVector<Constraint *> constraints;
607
618
llvm::SmallPtrSet<TypeVariableType *, 4 > typeVars;
608
619
llvm::SmallPtrSet<Constraint *, 8 > visitedConstraints;
609
620
610
- depthFirstSearch (*this , typeVar, typeVars, constraints, visitedConstraints);
611
- return constraints;
612
- }
621
+ if (kind == GatheringKind::AllMentions) {
622
+ // If we've been asked for "all mentions" of a type variable, search for
623
+ // constraints involving both it and its fixed bindings.
624
+ depthFirstSearch (
625
+ *this , typeVar,
626
+ [&](Constraint *constraint) {
627
+ if (acceptConstraintFn (constraint))
628
+ constraints.push_back (constraint);
629
+ },
630
+ typeVars, visitedConstraints);
631
+ return constraints;
632
+ }
613
633
614
- llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherNearbyConstraints (
615
- TypeVariableType *typeVar,
616
- llvm::function_ref<bool (Constraint *)> acceptConstraintFn) {
617
- llvm::TinyPtrVector<Constraint *> constraints;
618
- llvm::SmallPtrSet<TypeVariableType *, 4 > typeVars;
619
- llvm::SmallPtrSet<Constraint *, 8 > visitedConstraints;
634
+ // Otherwise only search in the type var's equivalence class and immediate
635
+ // fixed bindings.
620
636
621
637
// Local function to add constraints.
622
638
auto addTypeVarConstraints = [&](TypeVariableType *adjTypeVar) {
0 commit comments