Skip to content

Commit bcb3da0

Browse files
committed
[ConstraintGraph] NFC: Refactor {un}bindTypeVariable to remove unnecessary nesting
1 parent 5c623eb commit bcb3da0

File tree

1 file changed

+46
-45
lines changed

1 file changed

+46
-45
lines changed

Diff for: lib/Sema/ConstraintGraph.cpp

+46-45
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ void ConstraintGraphNode::introduceToInference(Constraint *constraint,
291291
bool notifyReferencedVars) {
292292
if (forRepresentativeVar()) {
293293
auto fixedType = TypeVar->getImpl().getFixedType(/*record=*/nullptr);
294-
if (!fixedType || fixedType->isTypeVariableOrMember())
294+
if (!fixedType)
295295
getCurrentBindings().infer(constraint);
296296
} else {
297297
auto *repr =
@@ -312,7 +312,7 @@ void ConstraintGraphNode::retractFromInference(Constraint *constraint,
312312
bool notifyReferencedVars) {
313313
if (forRepresentativeVar()) {
314314
auto fixedType = TypeVar->getImpl().getFixedType(/*record=*/nullptr);
315-
if (!fixedType || fixedType->isTypeVariableOrMember())
315+
if (!fixedType)
316316
getCurrentBindings().retract(constraint);
317317
} else {
318318
auto *repr =
@@ -539,65 +539,66 @@ void ConstraintGraph::bindTypeVariable(TypeVariableType *typeVar, Type fixed) {
539539
if (ActiveScope)
540540
Changes.push_back(Change::boundTypeVariable(typeVar, fixed));
541541

542-
// If there are no type variables in the fixed type, there's nothing to do.
543-
llvm::SmallPtrSet<TypeVariableType *, 4> typeVars;
542+
auto &node = (*this)[typeVar];
544543

545-
if (fixed->hasTypeVariable()) {
546-
fixed->getTypeVariables(typeVars);
544+
// Notify all of the type variables that reference this one.
545+
//
546+
// Since this type variable has been replaced with a fixed type
547+
// all of the concrete types that reference it are going to change,
548+
// which means that all of the not-yet-attempted bindings should
549+
// change as well.
550+
node.notifyReferencingVars();
547551

548-
auto &node = (*this)[typeVar];
549-
for (auto otherTypeVar : typeVars) {
550-
if (typeVar == otherTypeVar) continue;
552+
if (!fixed->hasTypeVariable())
553+
return;
551554

552-
auto &otherNode = (*this)[otherTypeVar];
555+
llvm::SmallPtrSet<TypeVariableType *, 4> typeVars;
556+
fixed->getTypeVariables(typeVars);
553557

554-
otherNode.addReferencedBy(typeVar);
555-
node.addReferencedVar(otherTypeVar);
558+
for (auto otherTypeVar : typeVars) {
559+
if (typeVar == otherTypeVar)
560+
continue;
556561

557-
// Newly referred vars need to re-introduce all constraints associated
558-
// with this type variable.
559-
for (auto *constraint : (*this)[typeVar].getConstraints()) {
560-
if (isUsefulForReferencedVars(constraint))
561-
otherNode.reintroduceToInference(constraint,
562-
/*notifyReferencedVars=*/false);
563-
}
564-
}
565-
}
562+
auto &otherNode = (*this)[otherTypeVar];
566563

567-
// All of the type variables associted with bound one need to trigger
568-
// re-introduction of constraints that reference them. That includes
569-
// whole equivalence class of the current type variable and all of its
570-
// fixed bindings.
571-
{
572-
(*this)[typeVar].notifyReferencingVars();
564+
otherNode.addReferencedBy(typeVar);
565+
node.addReferencedVar(otherTypeVar);
566+
567+
// Newly referred vars need to re-introduce all constraints associated
568+
// with this type variable since they are now going to be used in
569+
// all of the constraints that reference bound type variable.
570+
for (auto *constraint : (*this)[typeVar].getConstraints()) {
571+
if (isUsefulForReferencedVars(constraint))
572+
otherNode.reintroduceToInference(constraint,
573+
/*notifyReferencedVars=*/false);
574+
}
573575
}
574576
}
575577

576578
void ConstraintGraph::unbindTypeVariable(TypeVariableType *typeVar, Type fixed) {
577-
// All of the type variables associted with bound one need to trigger
578-
// re-introduction of constraints that reference them. That includes
579-
// whole equivalence class of the current type variable and all of its
580-
// fixed bindings.
581-
{
582-
auto &node = (*this)[typeVar];
579+
auto &node = (*this)[typeVar];
583580

584-
node.notifyReferencingVars();
581+
// Notify referencing variables (just like in bound case) that this
582+
// type variable has been modified.
583+
node.notifyReferencingVars();
585584

586-
llvm::SmallPtrSet<TypeVariableType *, 4> typeVars;
585+
if (!fixed->hasTypeVariable())
586+
return;
587587

588-
if (fixed->hasTypeVariable()) {
589-
fixed->getTypeVariables(typeVars);
588+
llvm::SmallPtrSet<TypeVariableType *, 4> typeVars;
589+
fixed->getTypeVariables(typeVars);
590590

591-
for (auto otherTypeVar : typeVars) {
592-
auto &otherNode = (*this)[otherTypeVar];
591+
for (auto otherTypeVar : typeVars) {
592+
auto &otherNode = (*this)[otherTypeVar];
593593

594-
otherNode.removeReferencedBy(typeVar);
595-
node.removeReference(otherTypeVar);
594+
otherNode.removeReferencedBy(typeVar);
595+
node.removeReference(otherTypeVar);
596596

597-
if (otherNode.forRepresentativeVar())
598-
otherNode.resetBindingSet();
599-
}
600-
}
597+
// TODO: This might be an overkill but it's (currently)
598+
// the simpliest way to reliably ensure that all of the
599+
// no longer related constraints have been retracted.
600+
if (otherNode.forRepresentativeVar())
601+
otherNode.resetBindingSet();
601602
}
602603
}
603604

0 commit comments

Comments
 (0)