@@ -199,7 +199,7 @@ void RewriteSystem::processMergedAssociatedTypes() {
199
199
const auto &lhs = pair.first ;
200
200
const auto &rhs = pair.second ;
201
201
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:
203
203
// X.[P1:T] => X.[P1&P2:T]
204
204
// X.[P2:T] => X.[P1&P2:T]
205
205
if (DebugMerge) {
@@ -216,18 +216,19 @@ void RewriteSystem::processMergedAssociatedTypes() {
216
216
MutableTerm mergedTerm = lhs;
217
217
mergedTerm.back () = mergedSymbol;
218
218
219
- // Add the rule X.[P1:T] => X.[P1&P2:T].
220
- addRule (lhs, mergedTerm);
221
-
222
219
// Add the rule X.[P1:T] => X.[P1&P2:T].
223
220
addRule (rhs, mergedTerm);
224
221
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.
227
227
SmallVector<std::pair<MutableTerm, MutableTerm>, 2 > inducedRules;
228
228
229
229
// 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];
231
232
const auto &otherLHS = otherRule.getLHS ();
232
233
if (otherLHS.size () == 2 &&
233
234
otherLHS[1 ].getKind () == Symbol::Kind::Protocol) {
@@ -260,7 +261,13 @@ void RewriteSystem::processMergedAssociatedTypes() {
260
261
inducedRules.emplace_back (newLHS, newRHS);
261
262
}
262
263
}
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);
264
271
265
272
// Now add the new rules.
266
273
for (const auto &pair : inducedRules)
0 commit comments