Skip to content

Commit 56450af

Browse files
committed
RequirementMachine: Record identity conformances in the property map
1 parent 3df1e72 commit 56450af

8 files changed

+26
-2
lines changed

lib/AST/RequirementMachine/PropertyMap.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,11 @@ PropertyMap::buildPropertyMap(unsigned maxIterations,
340340
if (rule.isSimplified())
341341
continue;
342342

343-
if (rule.isPermanent())
343+
// Identity conformances ([P].[P] => [P]) are permanent rules, but we
344+
// keep them around to ensure that concrete conformance introduction
345+
// works in the case where the protocol's Self type is itself subject
346+
// to a superclass or concrete type requirement.
347+
if (rule.isPermanent() && !rule.isIdentityConformanceRule())
344348
continue;
345349

346350
// Collect all rules of the form T.[p] => T where T is canonical.

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,7 @@ void RuleBuilder::collectRulesFromReferencedProtocols() {
10031003
llvm::dbgs() << "protocol " << proto->getName() << " {\n";
10041004
}
10051005

1006+
// Add the identity conformance rule [P].[P] => [P].
10061007
MutableTerm lhs;
10071008
lhs.add(Symbol::forProtocol(proto, Context));
10081009
lhs.add(Symbol::forProtocol(proto, Context));
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: not %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s
2+
3+
// CHECK-LABEL: circular_protocol_superclass.(file).A@
4+
// CHECK-NEXT: Requirement signature: <Self where Self : a>
5+
protocol A : a {
6+
associatedtype e : a
7+
}
8+
9+
class a : A {
10+
typealias e = a
11+
}

test/Generics/rdar79564324.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public func test<T : P>(_ t: T) where T == T.A {
3838
// CHECK-NEXT: Rewrite loops: {
3939
// CHECK: }
4040
// CHECK-NEXT: Property map: {
41+
// CHECK-NEXT: [P] => { conforms_to: [P] }
4142
// CHECK-NEXT: [P:A] => { conforms_to: [P] }
4243
// CHECK-NEXT: τ_0_1 => { conforms_to: [P] }
4344
// CHECK-NEXT: τ_0_0 => { conforms_to: [P] }

test/Generics/unify_superclass_types_1.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ extension P where Self : Derived {
2626
// CHECK-NEXT: Rewrite loops: {
2727
// CHECK: }
2828
// CHECK-NEXT: Property map: {
29-
// CHECK-NEXT: [P] => { layout: _NativeClass superclass: [superclass: Base] }
29+
// CHECK-NEXT: [P] => { conforms_to: [P] layout: _NativeClass superclass: [superclass: Base] }
3030
// CHECK-NEXT: τ_0_0 => { conforms_to: [P] layout: _NativeClass superclass: [superclass: Derived] }
3131
// CHECK-NEXT: }

test/Generics/unify_superclass_types_2.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
4444
// CHECK-NEXT: Rewrite loops: {
4545
// CHECK: }
4646
// CHECK-NEXT: Property map: {
47+
// CHECK-NEXT: [P1] => { conforms_to: [P1] }
48+
// CHECK-NEXT: [P2] => { conforms_to: [P2] }
4749
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Generic<Int, τ_0_0, τ_0_1> with <[P1:A1], [P1:B1]>] }
4850
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Generic<τ_0_0, String, τ_0_1> with <[P2:A2], [P2:B2]>] }
4951
// CHECK-NEXT: τ_0_0 => { conforms_to: [P1 P2] }

test/Generics/unify_superclass_types_3.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
4848
// CHECK-NEXT: Rewrite loops: {
4949
// CHECK: }
5050
// CHECK-NEXT: Property map: {
51+
// CHECK-NEXT: [P1] => { conforms_to: [P1] }
52+
// CHECK-NEXT: [P2] => { conforms_to: [P2] }
5153
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0, τ_0_1> with <[P1:A1], [P1:B1]>] }
5254
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Generic<τ_0_0, String, τ_0_1> with <[P2:A2], [P2:B2]>] }
5355
// CHECK-NEXT: τ_0_0 => { conforms_to: [P1 P2] }

test/Generics/unify_superclass_types_4.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
4747
// CHECK-NEXT: Rewrite loops: {
4848
// CHECK: }
4949
// CHECK-NEXT: Property map: {
50+
// CHECK-NEXT: [P1] => { conforms_to: [P1] }
51+
// CHECK-NEXT: [P2] => { conforms_to: [P2] }
52+
// CHECK-NEXT: [Q] => { conforms_to: [Q] }
5053
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Base<τ_0_0> with <[P1:A1]>] }
5154
// CHECK-NEXT: [P2:A2] => { conforms_to: [Q] }
5255
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0> with <[P2:A2]>] }

0 commit comments

Comments
 (0)