Skip to content

Commit 5689d04

Browse files
committed
RequirementMachine: Always add a rule for the trivial [P].[P] => [P] conformance
Completion adds this rule when a same-type requirement equates the Self of P with some other type parameter conforming to P; one example is something like this: protocol P { associatedtype T : P where T.T == Self } The initial rewrite system looks like this: (1) [P].T => [P:T] (2) [P:T].[P] => [P:T] (3) [P:T].[P:T] => [P] Rules (2) and (3) overlap on the term [P:T].[P:T].[P] Simplifying the overlapped term with rule (2) produces [P:T].[P:T] Which further reduces to [P] Simplifying the overlapped term with rule (3) produces [P].[P] So we get a new rule [P].[P] => [P] This is not a "real" conformance rule, and homotopy reduction wastes work unraveling it in rewrite loops where this rule occurs. Instead, it's better to introduce it as a permanent rule that is not subject to homotopy reduction for every protocol.
1 parent 6d89b42 commit 5689d04

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,15 @@ void RewriteSystemBuilder::processProtocolDependencies() {
275275
llvm::dbgs() << "protocol " << proto->getName() << " {\n";
276276
}
277277

278+
MutableTerm lhs;
279+
lhs.add(Symbol::forProtocol(proto, Context));
280+
lhs.add(Symbol::forProtocol(proto, Context));
281+
282+
MutableTerm rhs;
283+
rhs.add(Symbol::forProtocol(proto, Context));
284+
285+
AssociatedTypeRules.emplace_back(lhs, rhs);
286+
278287
for (auto *assocType : proto->getAssociatedTypeMembers())
279288
addAssociatedType(assocType, proto);
280289

test/Generics/rdar79564324.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ public func test<T : P>(_ t: T) where T == T.A {
2323

2424
// CHECK-LABEL: Requirement machine for <τ_0_0, τ_0_1 where τ_0_0 == τ_0_0.A, τ_0_1 : P, τ_0_0.A == τ_0_1.A>
2525
// CHECK-NEXT: Rewrite system: {
26-
// CHECK-NEXT: - [P].A => [P:A]
26+
// CHECK-NEXT: - [P].[P] => [P] [permanent]
27+
// CHECK-NEXT: - [P].A => [P:A] [permanent]
2728
// CHECK-NEXT: - [P:A].[P] => [P:A]
2829
// CHECK-NEXT: - τ_0_0.[P:A] => τ_0_0
2930
// CHECK-NEXT: - τ_0_1.[P] => τ_0_1
3031
// CHECK-NEXT: - τ_0_1.[P:A] => τ_0_0
32+
// CHECK-NEXT: - [P].[P:A] => [P:A]
3133
// CHECK-NEXT: - [P:A].A => [P:A].[P:A]
3234
// CHECK-NEXT: - τ_0_0.[P] => τ_0_0
3335
// CHECK-NEXT: - τ_0_1.A => τ_0_0

test/Generics/unify_superclass_types_1.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extension P where Self : Derived {
1515

1616
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : Derived, τ_0_0 : P>
1717
// CHECK-NEXT: Rewrite system: {
18+
// CHECK-NEXT: - [P].[P] => [P] [permanent]
1819
// CHECK-NEXT: - [P].[superclass: Base] => [P]
1920
// CHECK-NEXT: - [P].[layout: _NativeClass] => [P]
2021
// CHECK-NEXT: - τ_0_0.[superclass: Derived] => τ_0_0

0 commit comments

Comments
 (0)