Skip to content

Commit 2230c3a

Browse files
committed
Sema: Split up gatherConstraints() into gatherAllConstraints() and gatherNearbyConstraints()
The two GatherKinds no longer share any implementation, so there's no point keeping the logic together. Doing this also allows removing the acceptConstraintFn from gatherAllConstraints(), which further simplifies depthFirstSearch().
1 parent 881c4f7 commit 2230c3a

File tree

7 files changed

+37
-62
lines changed

7 files changed

+37
-62
lines changed

include/swift/Sema/ConstraintGraph.h

+10-17
Original file line numberDiff line numberDiff line change
@@ -300,25 +300,18 @@ class ConstraintGraph {
300300
/// to a type variable.
301301
void introduceToInference(TypeVariableType *typeVar, Type fixedType);
302302

303-
/// Describes which constraints \c gatherConstraints should gather.
304-
enum class GatheringKind {
305-
/// Gather constraints associated with all of the variables within the
306-
/// same equivalence class as the given type variable, as well as its
307-
/// immediate fixed bindings.
308-
EquivalenceClass,
309-
/// Gather all constraints that mention this type variable or type variables
310-
/// that it is a fixed binding of. Unlike EquivalenceClass, this looks
311-
/// through transitive fixed bindings. This can be used to find all the
312-
/// constraints that may be affected when binding a type variable.
313-
AllMentions,
314-
};
303+
/// Gather constraints associated with all of the variables within the
304+
/// same equivalence class as the given type variable, as well as its
305+
/// immediate fixed bindings.
306+
llvm::TinyPtrVector<Constraint *>
307+
gatherAllConstraints(TypeVariableType *typeVar);
315308

316-
/// Gather the set of constraints that involve the given type variable,
317-
/// i.e., those constraints that will be affected when the type variable
318-
/// gets merged or bound to a fixed type.
309+
/// Gather all constraints that mention this type variable or type variables
310+
/// that it is a fixed binding of. Unlike EquivalenceClass, this looks
311+
/// through transitive fixed bindings. This can be used to find all the
312+
/// constraints that may be affected when binding a type variable.
319313
llvm::TinyPtrVector<Constraint *>
320-
gatherConstraints(TypeVariableType *typeVar,
321-
GatheringKind kind,
314+
gatherNearbyConstraints(TypeVariableType *typeVar,
322315
llvm::function_ref<bool(Constraint *)> acceptConstraint =
323316
[](Constraint *constraint) { return true; });
324317

lib/Sema/CSOptimizer.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ NullablePtr<Constraint> getApplicableFnConstraint(ConstraintGraph &CG,
143143
if (!boundVar)
144144
return nullptr;
145145

146-
auto constraints = CG.gatherConstraints(
147-
boundVar, ConstraintGraph::GatheringKind::EquivalenceClass,
146+
auto constraints = CG.gatherNearbyConstraints(
147+
boundVar,
148148
[](Constraint *constraint) {
149149
return constraint->getKind() == ConstraintKind::ApplicableFunction;
150150
});
@@ -1129,8 +1129,8 @@ selectBestBindingDisjunction(ConstraintSystem &cs,
11291129
if (!firstBindDisjunction)
11301130
firstBindDisjunction = disjunction;
11311131

1132-
auto constraints = cs.getConstraintGraph().gatherConstraints(
1133-
typeVar, ConstraintGraph::GatheringKind::EquivalenceClass,
1132+
auto constraints = cs.getConstraintGraph().gatherNearbyConstraints(
1133+
typeVar,
11341134
[](Constraint *constraint) {
11351135
return constraint->getKind() == ConstraintKind::Conversion;
11361136
});

lib/Sema/CSSimplify.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -15843,8 +15843,8 @@ ConstraintSystem::addKeyPathApplicationRootConstraint(Type root, ConstraintLocat
1584315843
if (!typeVar)
1584415844
return;
1584515845

15846-
auto constraints = CG.gatherConstraints(
15847-
typeVar, ConstraintGraph::GatheringKind::EquivalenceClass,
15846+
auto constraints = CG.gatherNearbyConstraints(
15847+
typeVar,
1584815848
[&keyPathExpr](Constraint *constraint) -> bool {
1584915849
if (constraint->getKind() != ConstraintKind::KeyPath)
1585015850
return false;

lib/Sema/CSSolver.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -1309,8 +1309,8 @@ ConstraintSystem::findConstraintThroughOptionals(
13091309
while (visitedVars.insert(rep).second) {
13101310
// Look for a disjunction that binds this type variable to an overload set.
13111311
TypeVariableType *optionalObjectTypeVar = nullptr;
1312-
auto constraints = getConstraintGraph().gatherConstraints(
1313-
rep, ConstraintGraph::GatheringKind::EquivalenceClass,
1312+
auto constraints = getConstraintGraph().gatherNearbyConstraints(
1313+
rep,
13141314
[&](Constraint *match) {
13151315
// If we have an "optional object of" constraint, we may need to
13161316
// look through it to find the constraint we're looking for.
@@ -1918,9 +1918,8 @@ void DisjunctionChoice::propagateConversionInfo(ConstraintSystem &cs) const {
19181918
}
19191919
}
19201920

1921-
auto constraints = cs.CG.gatherConstraints(
1921+
auto constraints = cs.CG.gatherNearbyConstraints(
19221922
typeVar,
1923-
ConstraintGraph::GatheringKind::EquivalenceClass,
19241923
[](Constraint *constraint) -> bool {
19251924
switch (constraint->getKind()) {
19261925
case ConstraintKind::Conversion:

lib/Sema/ConstraintGraph.cpp

+15-31
Original file line numberDiff line numberDiff line change
@@ -552,18 +552,11 @@ void ConstraintGraph::retractBindings(TypeVariableType *typeVar,
552552

553553
#pragma mark Algorithms
554554

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.
562555
static void depthFirstSearch(
563556
ConstraintGraph &cg,
564557
TypeVariableType *typeVar,
565-
llvm::function_ref<void(Constraint *)> visitConstraint,
566558
llvm::SmallPtrSet<TypeVariableType *, 4> &typeVars,
559+
llvm::TinyPtrVector<Constraint *> &constraints,
567560
llvm::SmallPtrSet<Constraint *, 8> &visitedConstraints) {
568561
// If we're not looking at this type variable right now because we're
569562
// solving a conjunction element, don't consider its adjacencies.
@@ -577,11 +570,8 @@ static void depthFirstSearch(
577570
// Local function to visit adjacent type variables.
578571
auto visitAdjacencies = [&](ArrayRef<TypeVariableType *> adjTypeVars) {
579572
for (auto adj : adjTypeVars) {
580-
if (adj == typeVar)
581-
continue;
582-
583-
// Recurse into this node.
584-
depthFirstSearch(cg, adj, visitConstraint, typeVars, visitedConstraints);
573+
if (adj != typeVar)
574+
depthFirstSearch(cg, adj, typeVars, constraints, visitedConstraints);
585575
}
586576
};
587577

@@ -592,7 +582,7 @@ static void depthFirstSearch(
592582
if (!visitedConstraints.insert(constraint).second)
593583
continue;
594584

595-
visitConstraint(constraint);
585+
constraints.push_back(constraint);
596586
}
597587

598588
// Visit all of the other nodes in the equivalence class.
@@ -611,28 +601,22 @@ static void depthFirstSearch(
611601
visitAdjacencies(node.getReferencedVars());
612602
}
613603

614-
llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
615-
TypeVariableType *typeVar, GatheringKind kind,
616-
llvm::function_ref<bool(Constraint *)> acceptConstraintFn) {
604+
llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherAllConstraints(
605+
TypeVariableType *typeVar) {
617606
llvm::TinyPtrVector<Constraint *> constraints;
618607
llvm::SmallPtrSet<TypeVariableType *, 4> typeVars;
619608
llvm::SmallPtrSet<Constraint *, 8> visitedConstraints;
620609

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-
}
610+
depthFirstSearch(*this, typeVar, typeVars, constraints, visitedConstraints);
611+
return constraints;
612+
}
633613

634-
// Otherwise only search in the type var's equivalence class and immediate
635-
// fixed bindings.
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;
636620

637621
// Local function to add constraints.
638622
auto addTypeVarConstraints = [&](TypeVariableType *adjTypeVar) {

lib/Sema/ConstraintSystem.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,7 @@ void ConstraintSystem::assignFixedType(TypeVariableType *typeVar, Type type,
267267
void ConstraintSystem::addTypeVariableConstraintsToWorkList(
268268
TypeVariableType *typeVar) {
269269
// Activate the constraints affected by a change to this type variable.
270-
auto gatheringKind = ConstraintGraph::GatheringKind::AllMentions;
271-
for (auto *constraint : CG.gatherConstraints(typeVar, gatheringKind))
270+
for (auto *constraint : CG.gatherAllConstraints(typeVar))
272271
if (!constraint->isActive())
273272
activateConstraint(constraint);
274273
}

lib/Sema/TypeOfReference.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2044,8 +2044,8 @@ void ConstraintSystem::bindOverloadType(
20442044
increaseScore(SK_KeyPathSubscript, locator);
20452045

20462046
auto boundTypeVar = boundType->castTo<TypeVariableType>();
2047-
auto constraints = getConstraintGraph().gatherConstraints(
2048-
boundTypeVar, ConstraintGraph::GatheringKind::EquivalenceClass,
2047+
auto constraints = getConstraintGraph().gatherNearbyConstraints(
2048+
boundTypeVar,
20492049
[](Constraint *constraint) {
20502050
return constraint->getKind() == ConstraintKind::ApplicableFunction;
20512051
});

0 commit comments

Comments
 (0)