Skip to content

Commit 1d5fdc3

Browse files
committed
RequirementMachine: Implement linear order on concrete type symbols with the same concrete type
1 parent ee79c9f commit 1d5fdc3

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

lib/AST/RequirementMachine/Symbol.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,17 +623,42 @@ int Symbol::compare(Symbol other, RewriteContext &ctx) const {
623623
auto *proto = getProtocol();
624624
auto *otherProto = other.getProtocol();
625625

626+
// For concrete conformance symbols, order by protocol first.
626627
result = ctx.compareProtocols(proto, otherProto);
627-
break;
628+
if (result != 0)
629+
return result;
630+
631+
// Then, check if they have the same concrete type and order
632+
// substitutions.
633+
LLVM_FALLTHROUGH;
628634
}
629635

630636
case Kind::Superclass:
631-
case Kind::ConcreteType:
637+
case Kind::ConcreteType: {
638+
if (kind == Kind::Superclass
639+
? (getSuperclass() == other.getSuperclass())
640+
: (getConcreteType() == other.getConcreteType())) {
641+
642+
// If the concrete types are identical, compare substitution terms.
643+
assert(getSubstitutions().size() == other.getSubstitutions().size());
644+
for (unsigned i : indices(getSubstitutions())) {
645+
auto term = getSubstitutions()[i];
646+
auto otherTerm = other.getSubstitutions()[i];
647+
648+
result = term.compare(otherTerm, ctx);
649+
if (result != 0)
650+
return result;
651+
}
652+
653+
break;
654+
}
655+
656+
// We don't support comparing arbitrary concrete types.
632657
llvm::errs() << "Cannot compare concrete types yet\n";
633658
llvm::errs() << "LHS: " << *this << "\n";
634659
llvm::errs() << "RHS: " << other << "\n";
635660
abort();
636-
661+
}
637662
}
638663

639664
if (result == 0) {

0 commit comments

Comments
 (0)