Skip to content

Commit 3e863ff

Browse files
committed
RequirementMachine: Fix up concrete type atoms when computing overlaps
1 parent f1d2bcb commit 3e863ff

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

include/swift/AST/RewriteSystem.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ class Atom final {
125125
public:
126126
Kind getKind() const;
127127

128+
bool isSuperclassOrConcreteType() const {
129+
auto kind = getKind();
130+
return (kind == Kind::Superclass || kind == Kind::ConcreteType);
131+
}
132+
128133
Identifier getName() const;
129134

130135
const ProtocolDecl *getProtocol() const;
@@ -176,6 +181,10 @@ class Atom final {
176181

177182
int compare(Atom other, const ProtocolGraph &protos) const;
178183

184+
Atom prependPrefixToConcreteSubstitutions(
185+
const MutableTerm &prefix,
186+
RewriteContext &ctx) const;
187+
179188
void dump(llvm::raw_ostream &out) const;
180189

181190
friend bool operator==(Atom lhs, Atom rhs) {
@@ -276,6 +285,10 @@ class MutableTerm final {
276285
Atoms.push_back(atom);
277286
}
278287

288+
void append(Term other) {
289+
Atoms.append(other.begin(), other.end());
290+
}
291+
279292
void append(const MutableTerm &other) {
280293
Atoms.append(other.begin(), other.end());
281294
}

lib/AST/RewriteSystem.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,52 @@ int Atom::compare(Atom other, const ProtocolGraph &graph) const {
488488
return result;
489489
}
490490

491+
/// For a superclass or concrete type atom
492+
///
493+
/// [concrete: Foo<X1, ..., Xn>]
494+
/// [superclass: Foo<X1, ..., Xn>]
495+
///
496+
/// Return a new atom where the prefix T is prepended to each of the
497+
/// substitutions:
498+
///
499+
/// [concrete: Foo<T.X1, ..., T.Xn>]
500+
/// [superclass: Foo<T.X1, ..., T.Xn>]
501+
///
502+
/// Asserts if this is not a superclass or concrete type atom.
503+
Atom Atom::prependPrefixToConcreteSubstitutions(
504+
const MutableTerm &prefix,
505+
RewriteContext &ctx) const {
506+
assert(isSuperclassOrConcreteType());
507+
508+
if (prefix.empty())
509+
return *this;
510+
511+
SmallVector<Term, 2> substitutions;
512+
for (auto term : getSubstitutions()) {
513+
MutableTerm mutTerm;
514+
mutTerm.append(prefix);
515+
mutTerm.append(term);
516+
517+
substitutions.push_back(Term::get(mutTerm, ctx));
518+
}
519+
520+
switch (getKind()) {
521+
case Kind::Superclass:
522+
return Atom::forSuperclass(getSuperclass(), substitutions, ctx);
523+
case Kind::ConcreteType:
524+
return Atom::forConcreteType(getConcreteType(), substitutions, ctx);
525+
526+
case Kind::GenericParam:
527+
case Kind::Name:
528+
case Kind::Protocol:
529+
case Kind::AssociatedType:
530+
case Kind::Layout:
531+
break;
532+
}
533+
534+
llvm_unreachable("Bad atom kind");
535+
}
536+
491537
/// Print the atom using our mnemonic representation.
492538
void Atom::dump(llvm::raw_ostream &out) const {
493539
auto dumpSubstitutions = [&]() {
@@ -1286,6 +1332,11 @@ RewriteSystem::computeCriticalPair(const Rule &lhs, const Rule &rhs) const {
12861332
case OverlapKind::Second: {
12871333
// lhs == TU -> X, rhs == UV -> Y.
12881334

1335+
if (v.back().isSuperclassOrConcreteType()) {
1336+
v.back() = v.back().prependPrefixToConcreteSubstitutions(
1337+
t, Context);
1338+
}
1339+
12891340
// Compute the term XV.
12901341
MutableTerm xv;
12911342
xv.append(lhs.getRHS());

0 commit comments

Comments
 (0)