@@ -418,16 +418,25 @@ void MinimalConformances::collectConformanceRules() {
418418
419419 // Sort the list of conformance rules in reverse order; we're going to try
420420 // to minimize away less canonical rules first.
421- std::sort (ConformanceRules.begin (), ConformanceRules.end (),
422- [&](unsigned lhs, unsigned rhs) -> bool {
423- const auto &lhsRule = System.getRule (lhs);
424- const auto &rhsRule = System.getRule (rhs);
425-
426- if (lhsRule.isExplicit () != rhsRule.isExplicit ())
427- return !lhsRule.isExplicit ();
428-
429- return *lhsRule.getLHS ().compare (rhsRule.getLHS (), Context) > 0 ;
430- });
421+ std::stable_sort (ConformanceRules.begin (), ConformanceRules.end (),
422+ [&](unsigned lhs, unsigned rhs) -> bool {
423+ const auto &lhsRule = System.getRule (lhs);
424+ const auto &rhsRule = System.getRule (rhs);
425+
426+ if (lhsRule.isExplicit () != rhsRule.isExplicit ())
427+ return !lhsRule.isExplicit ();
428+
429+ auto result = lhsRule.getLHS ().compare (rhsRule.getLHS (), Context);
430+
431+ // Concrete conformance rules are unordered if they name the
432+ // same protocol but have different types. This can come up
433+ // if we have a class inheritance relationship 'Derived : Base',
434+ // and Base conforms to a protocol:
435+ //
436+ // T.[Base : P] => T
437+ // T.[Derived : P] => T
438+ return (result ? *result > 0 : 0 );
439+ });
431440
432441 Context.ConformanceRulesHistogram .add (ConformanceRules.size ());
433442}
0 commit comments