@@ -291,7 +291,7 @@ void ConstraintGraphNode::introduceToInference(Constraint *constraint,
291
291
bool notifyReferencedVars) {
292
292
if (forRepresentativeVar ()) {
293
293
auto fixedType = TypeVar->getImpl ().getFixedType (/* record=*/ nullptr );
294
- if (!fixedType || fixedType-> isTypeVariableOrMember () )
294
+ if (!fixedType)
295
295
getCurrentBindings ().infer (constraint);
296
296
} else {
297
297
auto *repr =
@@ -312,7 +312,7 @@ void ConstraintGraphNode::retractFromInference(Constraint *constraint,
312
312
bool notifyReferencedVars) {
313
313
if (forRepresentativeVar ()) {
314
314
auto fixedType = TypeVar->getImpl ().getFixedType (/* record=*/ nullptr );
315
- if (!fixedType || fixedType-> isTypeVariableOrMember () )
315
+ if (!fixedType)
316
316
getCurrentBindings ().retract (constraint);
317
317
} else {
318
318
auto *repr =
@@ -539,65 +539,66 @@ void ConstraintGraph::bindTypeVariable(TypeVariableType *typeVar, Type fixed) {
539
539
if (ActiveScope)
540
540
Changes.push_back (Change::boundTypeVariable (typeVar, fixed));
541
541
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];
544
543
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 ();
547
551
548
- auto &node = (*this )[typeVar];
549
- for (auto otherTypeVar : typeVars) {
550
- if (typeVar == otherTypeVar) continue ;
552
+ if (!fixed->hasTypeVariable ())
553
+ return ;
551
554
552
- auto &otherNode = (*this )[otherTypeVar];
555
+ llvm::SmallPtrSet<TypeVariableType *, 4 > typeVars;
556
+ fixed->getTypeVariables (typeVars);
553
557
554
- otherNode.addReferencedBy (typeVar);
555
- node.addReferencedVar (otherTypeVar);
558
+ for (auto otherTypeVar : typeVars) {
559
+ if (typeVar == otherTypeVar)
560
+ continue ;
556
561
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];
566
563
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
+ }
573
575
}
574
576
}
575
577
576
578
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];
583
580
584
- node.notifyReferencingVars ();
581
+ // Notify referencing variables (just like in bound case) that this
582
+ // type variable has been modified.
583
+ node.notifyReferencingVars ();
585
584
586
- llvm::SmallPtrSet<TypeVariableType *, 4 > typeVars;
585
+ if (!fixed->hasTypeVariable ())
586
+ return ;
587
587
588
- if (fixed-> hasTypeVariable ()) {
589
- fixed->getTypeVariables (typeVars);
588
+ llvm::SmallPtrSet<TypeVariableType *, 4 > typeVars;
589
+ fixed->getTypeVariables (typeVars);
590
590
591
- for (auto otherTypeVar : typeVars) {
592
- auto &otherNode = (*this )[otherTypeVar];
591
+ for (auto otherTypeVar : typeVars) {
592
+ auto &otherNode = (*this )[otherTypeVar];
593
593
594
- otherNode.removeReferencedBy (typeVar);
595
- node.removeReference (otherTypeVar);
594
+ otherNode.removeReferencedBy (typeVar);
595
+ node.removeReference (otherTypeVar);
596
596
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 ();
601
602
}
602
603
}
603
604
0 commit comments