@@ -199,7 +199,7 @@ void RewriteSystem::processMergedAssociatedTypes() {
199199 const auto &lhs = pair.first ;
200200 const auto &rhs = pair.second ;
201201
202- // If we have X.[P1 :T] => Y.[P2 :T], add a new pair of rules:
202+ // If we have X.[P2 :T] => Y.[P1 :T], add a new pair of rules:
203203 // X.[P1:T] => X.[P1&P2:T]
204204 // X.[P2:T] => X.[P1&P2:T]
205205 if (DebugMerge) {
@@ -216,18 +216,19 @@ void RewriteSystem::processMergedAssociatedTypes() {
216216 MutableTerm mergedTerm = lhs;
217217 mergedTerm.back () = mergedSymbol;
218218
219- // Add the rule X.[P1:T] => X.[P1&P2:T].
220- addRule (lhs, mergedTerm);
221-
222219 // Add the rule X.[P1:T] => X.[P1&P2:T].
223220 addRule (rhs, mergedTerm);
224221
225- // Collect new rules here so that we're not adding rules while iterating
226- // over the rules list.
222+ // Add the rule X.[P2:T] => X.[P1&P2:T].
223+ addRule (lhs, mergedTerm);
224+
225+ // Collect new rules here so that we're not adding rules while traversing
226+ // the trie.
227227 SmallVector<std::pair<MutableTerm, MutableTerm>, 2 > inducedRules;
228228
229229 // Look for conformance requirements on [P1:T] and [P2:T].
230- for (const auto &otherRule : Rules) {
230+ auto visitRule = [&](unsigned ruleID) {
231+ const auto &otherRule = Rules[ruleID];
231232 const auto &otherLHS = otherRule.getLHS ();
232233 if (otherLHS.size () == 2 &&
233234 otherLHS[1 ].getKind () == Symbol::Kind::Protocol) {
@@ -260,7 +261,13 @@ void RewriteSystem::processMergedAssociatedTypes() {
260261 inducedRules.emplace_back (newLHS, newRHS);
261262 }
262263 }
263- }
264+ };
265+
266+ // Visit rhs first to preserve the ordering of protocol requirements in the
267+ // the property map. This is just for aesthetic purposes in the debug dump,
268+ // it doesn't change behavior.
269+ Trie.findAll (rhs.back (), visitRule);
270+ Trie.findAll (lhs.back (), visitRule);
264271
265272 // Now add the new rules.
266273 for (const auto &pair : inducedRules)
0 commit comments