@@ -960,6 +960,56 @@ void BindingSet::addLiteralRequirement(Constraint *constraint) {
960960 Literals.insert ({protocol, std::move (literal)});
961961}
962962
963+ bool BindingSet::operator ==(const BindingSet &other) {
964+ if (AdjacentVars != other.AdjacentVars )
965+ return false ;
966+
967+ if (Bindings.size () != other.Bindings .size ())
968+ return false ;
969+
970+ for (auto i : indices (Bindings)) {
971+ const auto &x = Bindings[i];
972+ const auto &y = other.Bindings [i];
973+
974+ if (x.BindingType .getPointer () != y.BindingType .getPointer () ||
975+ x.Kind != y.Kind )
976+ return false ;
977+ }
978+
979+ if (Literals.size () != other.Literals .size ())
980+ return false ;
981+
982+ for (auto pair : Literals) {
983+ auto found = other.Literals .find (pair.first );
984+ if (found == other.Literals .end ())
985+ return false ;
986+
987+ const auto &x = pair.second ;
988+ const auto &y = found->second ;
989+
990+ if (x.Source != y.Source ||
991+ x.DefaultType .getPointer () != y.DefaultType .getPointer () ||
992+ x.IsDirectRequirement != y.IsDirectRequirement ) {
993+ return false ;
994+ }
995+ }
996+
997+ if (Defaults.size () != other.Defaults .size ())
998+ return false ;
999+
1000+ for (auto pair : Defaults) {
1001+ auto found = other.Defaults .find (pair.first );
1002+ if (found == other.Defaults .end () ||
1003+ pair.second != found->second )
1004+ return false ;
1005+ }
1006+
1007+ if (TransitiveProtocols != other.TransitiveProtocols )
1008+ return false ;
1009+
1010+ return true ;
1011+ }
1012+
9631013BindingSet::BindingScore BindingSet::formBindingScore (const BindingSet &b) {
9641014 // If there are no bindings available but this type
9651015 // variable represents a closure - let's consider it
@@ -980,6 +1030,43 @@ BindingSet::BindingScore BindingSet::formBindingScore(const BindingSet &b) {
9801030 -numNonDefaultableBindings);
9811031}
9821032
1033+ bool BindingSet::operator <(const BindingSet &other) {
1034+ auto xScore = formBindingScore (*this );
1035+ auto yScore = formBindingScore (other);
1036+
1037+ if (xScore < yScore)
1038+ return true ;
1039+
1040+ if (yScore < xScore)
1041+ return false ;
1042+
1043+ auto xDefaults = getNumViableDefaultableBindings ();
1044+ auto yDefaults = other.getNumViableDefaultableBindings ();
1045+
1046+ // If there is a difference in number of default types,
1047+ // prioritize bindings with fewer of them.
1048+ if (xDefaults != yDefaults)
1049+ return xDefaults < yDefaults;
1050+
1051+ // If neither type variable is a "hole" let's check whether
1052+ // there is a subtype relationship between them and prefer
1053+ // type variable which represents superclass first in order
1054+ // for "subtype" type variable to attempt more bindings later.
1055+ // This is required because algorithm can't currently infer
1056+ // bindings for subtype transitively through superclass ones.
1057+ if (!(std::get<0 >(xScore) && std::get<0 >(yScore))) {
1058+ if (Info.isSubtypeOf (other.getTypeVariable ()))
1059+ return false ;
1060+
1061+ if (other.Info .isSubtypeOf (getTypeVariable ()))
1062+ return true ;
1063+ }
1064+
1065+ // As a last resort, let's check if the bindings are
1066+ // potentially incomplete, and if so, let's de-prioritize them.
1067+ return isPotentiallyIncomplete () < other.isPotentiallyIncomplete ();
1068+ }
1069+
9831070std::optional<BindingSet> ConstraintSystem::determineBestBindings (
9841071 llvm::function_ref<void (const BindingSet &)> onCandidate) {
9851072 // Look for potential type variable bindings.
0 commit comments