@@ -133,8 +133,8 @@ bool BindingSet::involvesTypeVariables() const {
133
133
// on each step of the solver, but once bindings are computed
134
134
// incrementally it becomes more important to double-check that
135
135
// any adjacent type variables found previously are still unresolved.
136
- return llvm::any_of (Info. AdjacentVars , [](const auto &adjacent ) {
137
- return !adjacent. first ->getImpl ().getFixedType (/* record=*/ nullptr );
136
+ return llvm::any_of (AdjacentVars, [](TypeVariableType *typeVar ) {
137
+ return !typeVar ->getImpl ().getFixedType (/* record=*/ nullptr );
138
138
});
139
139
}
140
140
@@ -485,6 +485,27 @@ void BindingSet::addBinding(PotentialBinding binding) {
485
485
if (Bindings.count (binding))
486
486
return ;
487
487
488
+ if (!isViable (binding))
489
+ return ;
490
+
491
+ SmallPtrSet<TypeVariableType *, 4 > referencedTypeVars;
492
+ binding.BindingType ->getTypeVariables (referencedTypeVars);
493
+
494
+ // If type variable is not allowed to bind to `lvalue`,
495
+ // let's check if type of potential binding has any
496
+ // type variables, which are allowed to bind to `lvalue`,
497
+ // and postpone such type from consideration.
498
+ //
499
+ // This check is done here and not in `checkTypeOfBinding`
500
+ // because the l-valueness of the variable might change during
501
+ // solving and that would not be reflected in the graph.
502
+ if (!TypeVar->getImpl ().canBindToLValue ()) {
503
+ for (auto *typeVar : referencedTypeVars) {
504
+ if (typeVar->getImpl ().canBindToLValue ())
505
+ return ;
506
+ }
507
+ }
508
+
488
509
// If this is a non-defaulted supertype binding,
489
510
// check whether we can combine it with another
490
511
// supertype binding by computing the 'join' of the types.
@@ -558,8 +579,10 @@ void BindingSet::addBinding(PotentialBinding binding) {
558
579
}
559
580
}
560
581
561
- Bindings.insert (std::move (binding));
562
- >>>>>>> [CSBindings] Separate inference from final product
582
+ for (auto *adjacentVar : referencedTypeVars)
583
+ AdjacentVars.insert (adjacentVar);
584
+
585
+ (void )Bindings.insert (std::move (binding));
563
586
}
564
587
565
588
void BindingSet::addLiteralRequirement (Constraint *constraint) {
@@ -674,8 +697,9 @@ Optional<BindingSet> ConstraintSystem::determineBestBindings() {
674
697
675
698
// First, let's collect all of the possible bindings.
676
699
for (auto *typeVar : getTypeVariables ()) {
677
- if (!typeVar->getImpl ().hasRepresentativeOrFixed ())
678
- cache.insert ({typeVar, inferBindingsFor (typeVar, /* finalize=*/ false )});
700
+ if (!typeVar->getImpl ().hasRepresentativeOrFixed ()) {
701
+ cache.insert ({typeVar, getBindingsFor (typeVar)});
702
+ }
679
703
}
680
704
681
705
// Determine whether given type variable with its set of bindings is
@@ -711,7 +735,6 @@ Optional<BindingSet> ConstraintSystem::determineBestBindings() {
711
735
continue ;
712
736
713
737
auto &bindings = cachedBindings->getSecond ();
714
-
715
738
// Before attempting to infer transitive bindings let's check
716
739
// whether there are any viable "direct" bindings associated with
717
740
// current type variable, if there are none - it means that this type
@@ -729,11 +752,9 @@ Optional<BindingSet> ConstraintSystem::determineBestBindings() {
729
752
if (!bindings || !isViable)
730
753
continue ;
731
754
732
- /*
733
755
if (isDebugMode ()) {
734
756
bindings.dump (typeVar, llvm::errs (), solverState->depth * 2 );
735
757
}
736
- */
737
758
738
759
// If these are the first bindings, or they are better than what
739
760
// we saw before, use them instead.
@@ -867,17 +888,14 @@ void PotentialBindings::addPotentialBinding(PotentialBinding binding) {
867
888
binding = binding.withType (binding.BindingType ->getRValueType ());
868
889
}
869
890
870
- if (!isViable (binding))
871
- return ;
872
-
873
891
Bindings.push_back (std::move (binding));
874
892
}
875
893
876
894
void PotentialBindings::addLiteral (Constraint *constraint) {
877
895
Literals.insert (constraint);
878
896
}
879
897
880
- bool PotentialBindings ::isViable (PotentialBinding &binding) const {
898
+ bool BindingSet ::isViable (PotentialBinding &binding) const {
881
899
// Prevent against checking against the same opened nominal type
882
900
// over and over again. Doing so means redundant work in the best
883
901
// case. In the worst case, we'll produce lots of duplicate solutions
@@ -891,7 +909,7 @@ bool PotentialBindings::isViable(PotentialBinding &binding) const {
891
909
892
910
for (auto &existing : Bindings) {
893
911
auto *existingNTD = existing.BindingType ->getAnyNominal ();
894
- if (existingNTD && NTD == existingNTD)
912
+ if (existingNTD && NTD == existingNTD && existing. Kind == binding. Kind )
895
913
return false ;
896
914
}
897
915
}
@@ -929,29 +947,12 @@ bool BindingSet::favoredOverDisjunction(Constraint *disjunction) const {
929
947
return !involvesTypeVariables ();
930
948
}
931
949
932
- BindingSet ConstraintSystem::inferBindingsFor (TypeVariableType *typeVar,
933
- bool finalize) {
950
+ BindingSet ConstraintSystem::getBindingsFor (TypeVariableType *typeVar) {
934
951
assert (typeVar->getImpl ().getRepresentative (nullptr ) == typeVar &&
935
952
" not a representative" );
936
953
assert (!typeVar->getImpl ().getFixedType (nullptr ) && " has a fixed type" );
937
954
938
- PotentialBindings bindings (*this , typeVar);
939
-
940
- // Gather the constraints associated with this type variable.
941
- auto constraints = CG.gatherConstraints (
942
- typeVar, ConstraintGraph::GatheringKind::EquivalenceClass);
943
-
944
- for (auto *constraint : constraints)
945
- bindings.infer (constraint);
946
-
947
- BindingSet result{bindings};
948
-
949
- if (finalize) {
950
- llvm::SmallDenseMap<TypeVariableType *, BindingSet> inferred;
951
- result.finalize (inferred);
952
- }
953
-
954
- return result;
955
+ return {CG[typeVar].getCurrentBindings ()};
955
956
}
956
957
957
958
// / Check whether the given type can be used as a binding for the given
@@ -960,20 +961,11 @@ BindingSet ConstraintSystem::inferBindingsFor(TypeVariableType *typeVar,
960
961
// / \returns the type to bind to, if the binding is okay.
961
962
static Optional<Type> checkTypeOfBinding (TypeVariableType *typeVar, Type type) {
962
963
// If the type references the type variable, don't permit the binding.
963
- SmallPtrSet<TypeVariableType *, 4 > referencedTypeVars;
964
- type->getTypeVariables (referencedTypeVars);
965
- if (referencedTypeVars.count (typeVar))
966
- return None;
967
-
968
- // If type variable is not allowed to bind to `lvalue`,
969
- // let's check if type of potential binding has any
970
- // type variables, which are allowed to bind to `lvalue`,
971
- // and postpone such type from consideration.
972
- if (!typeVar->getImpl ().canBindToLValue ()) {
973
- for (auto *typeVar : referencedTypeVars) {
974
- if (typeVar->getImpl ().canBindToLValue ())
975
- return None;
976
- }
964
+ if (type->hasTypeVariable ()) {
965
+ SmallPtrSet<TypeVariableType *, 4 > referencedTypeVars;
966
+ type->getTypeVariables (referencedTypeVars);
967
+ if (referencedTypeVars.count (typeVar))
968
+ return None;
977
969
}
978
970
979
971
{
@@ -1117,13 +1109,6 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
1117
1109
// Check whether we can perform this binding.
1118
1110
if (auto boundType = checkTypeOfBinding (TypeVar, type)) {
1119
1111
type = *boundType;
1120
- if (type->hasTypeVariable ()) {
1121
- llvm::SmallPtrSet<TypeVariableType *, 4 > referencedVars;
1122
- type->getTypeVariables (referencedVars);
1123
- for (auto *var : referencedVars) {
1124
- AdjacentVars.insert ({var, constraint});
1125
- }
1126
- }
1127
1112
} else {
1128
1113
auto *bindingTypeVar = type->getRValueType ()->getAs <TypeVariableType>();
1129
1114
0 commit comments