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