@@ -1040,19 +1040,37 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
1040
1040
}
1041
1041
1042
1042
// Compare the type variable bindings.
1043
- for (auto &binding : diff.typeBindings ) {
1043
+ llvm::DenseMap<TypeVariableType *, std::pair<Type, Type>> typeDiff;
1044
+
1045
+ const auto &bindings1 = solutions[idx1].typeBindings ;
1046
+ const auto &bindings2 = solutions[idx2].typeBindings ;
1047
+
1048
+ for (const auto &binding1 : bindings1) {
1049
+ auto *typeVar = binding1.first ;
1050
+
1044
1051
// If the type variable isn't one for which we should be looking at the
1045
1052
// bindings, don't.
1046
- if (!binding. typeVar ->getImpl ().prefersSubtypeBinding ())
1053
+ if (!typeVar->getImpl ().prefersSubtypeBinding ())
1047
1054
continue ;
1048
1055
1049
- auto type1 = binding.bindings [idx1];
1050
- auto type2 = binding.bindings [idx2];
1051
-
1052
- // If the types are equivalent, there's nothing more to do.
1053
- if (type1->isEqual (type2))
1056
+ // If both solutions have a binding for this type variable
1057
+ // let's consider it.
1058
+ auto binding2 = bindings2.find (typeVar);
1059
+ if (binding2 == bindings2.end ())
1054
1060
continue ;
1055
-
1061
+
1062
+ auto concreteType1 = binding1.second ;
1063
+ auto concreteType2 = binding2->second ;
1064
+
1065
+ if (!concreteType1->isEqual (concreteType2)) {
1066
+ typeDiff.insert ({typeVar, {concreteType1, concreteType2}});
1067
+ }
1068
+ }
1069
+
1070
+ for (auto &binding : typeDiff) {
1071
+ auto type1 = binding.second .first ;
1072
+ auto type2 = binding.second .second ;
1073
+
1056
1074
// If either of the types still contains type variables, we can't
1057
1075
// compare them.
1058
1076
// FIXME: This is really unfortunate. More type variable sharing
@@ -1128,7 +1146,7 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
1128
1146
}
1129
1147
}
1130
1148
}
1131
-
1149
+
1132
1150
// All other things considered equal, if any overload choice is more
1133
1151
// more constrained than the other, increment the score.
1134
1152
if (score1 == score2) {
@@ -1315,12 +1333,6 @@ SolutionDiff::SolutionDiff(ArrayRef<Solution> solutions) {
1315
1333
if (solutions.size () <= 1 )
1316
1334
return ;
1317
1335
1318
- // Populate the type bindings with the first solution.
1319
- llvm::DenseMap<TypeVariableType *, SmallVector<Type, 2 >> typeBindings;
1320
- for (auto binding : solutions[0 ].typeBindings ) {
1321
- typeBindings[binding.first ].push_back (binding.second );
1322
- }
1323
-
1324
1336
// Populate the overload choices with the first solution.
1325
1337
llvm::DenseMap<ConstraintLocator *, SmallVector<OverloadChoice, 2 >>
1326
1338
overloadChoices;
@@ -1331,27 +1343,6 @@ SolutionDiff::SolutionDiff(ArrayRef<Solution> solutions) {
1331
1343
// Find the type variables and overload locators common to all of the
1332
1344
// solutions.
1333
1345
for (auto &solution : solutions.slice (1 )) {
1334
- // For each type variable bound in all of the previous solutions, check
1335
- // whether we have a binding for this type variable in this solution.
1336
- SmallVector<TypeVariableType *, 4 > removeTypeBindings;
1337
- for (auto &binding : typeBindings) {
1338
- auto known = solution.typeBindings .find (binding.first );
1339
- if (known == solution.typeBindings .end ()) {
1340
- removeTypeBindings.push_back (binding.first );
1341
- continue ;
1342
- }
1343
-
1344
- // Add this solution's binding to the results.
1345
- binding.second .push_back (known->second );
1346
- }
1347
-
1348
- // Remove those type variables for which this solution did not have a
1349
- // binding.
1350
- for (auto typeVar : removeTypeBindings) {
1351
- typeBindings.erase (typeVar);
1352
- }
1353
- removeTypeBindings.clear ();
1354
-
1355
1346
// For each overload locator for which we have an overload choice in
1356
1347
// all of the previous solutions. Check whether we have an overload choice
1357
1348
// in this solution.
@@ -1374,26 +1365,6 @@ SolutionDiff::SolutionDiff(ArrayRef<Solution> solutions) {
1374
1365
}
1375
1366
}
1376
1367
1377
- // Look through the type variables that have bindings in all of the
1378
- // solutions, and add those that have differences to the diff.
1379
- for (auto &binding : typeBindings) {
1380
- Type singleType;
1381
- for (auto type : binding.second ) {
1382
- if (!singleType)
1383
- singleType = type;
1384
- else if (!singleType->isEqual (type)) {
1385
- // We have a difference. Add this binding to the diff.
1386
- this ->typeBindings .push_back (
1387
- SolutionDiff::TypeBindingDiff{
1388
- binding.first ,
1389
- std::move (binding.second )
1390
- });
1391
-
1392
- break ;
1393
- }
1394
- }
1395
- }
1396
-
1397
1368
for (auto &overloadChoice : overloadChoices) {
1398
1369
OverloadChoice singleChoice = overloadChoice.second [0 ];
1399
1370
for (auto choice : overloadChoice.second ) {
0 commit comments