Skip to content

Commit c092599

Browse files
committed
RequirementMachine: Skip associated type merge candidate if we're not going to get anything new
If we have a rule X.[P:A] => X.[Q:A] And Q inherits from P, then the merged symbol is [Q:A] and not [P&Q:A]. In this case, the merge operation won't produce any new rules, so we can just skip it entirely.
1 parent 6ec2aad commit c092599

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

lib/AST/RequirementMachine/RewriteSystemCompletion.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,22 @@ void RewriteSystem::processMergedAssociatedTypes() {
227227
llvm::dbgs() << "### Merged symbol " << mergedSymbol << "\n";
228228
}
229229

230+
// We must have mergedSymbol <= rhs < lhs, therefore mergedSymbol != lhs.
231+
assert(lhs.back() != mergedSymbol &&
232+
"Left hand side should not already end with merged symbol?");
233+
assert(mergedSymbol.compare(rhs.back(), Protos) <= 0);
234+
assert(rhs.back().compare(lhs.back(), Protos) < 0);
235+
236+
// If the merge didn't actually produce a new symbol, there is nothing else
237+
// to do.
238+
if (rhs.back() == mergedSymbol) {
239+
if (Debug.contains(DebugFlags::Merge)) {
240+
llvm::dbgs() << "### Skipping\n";
241+
}
242+
243+
continue;
244+
}
245+
230246
// Build the term X.[P1&P2:T].
231247
MutableTerm mergedTerm = lhs;
232248
mergedTerm.back() = mergedSymbol;
@@ -470,5 +486,8 @@ RewriteSystem::computeConfluentCompletion(unsigned maxIterations,
470486
processMergedAssociatedTypes();
471487
} while (again);
472488

489+
assert(MergedAssociatedTypes.empty() &&
490+
"Should have processed all merge candidates");
491+
473492
return std::make_pair(CompletionResult::Success, steps);
474493
}

0 commit comments

Comments
 (0)