Skip to content

Commit e240310

Browse files
committed
RequirementMachine: Disable merged associated types by default
This feature allows the following construct to work: protocol P1 { associatedtype T : P1 } protocol P2 { associatedtype T : P2 } func foo<T : P1 & P2>(_: T) {} However, I haven't figured out how to make it work with rewrite system minimization, so it's already disabled when you use the requirement machine for protocol or generic signature minimization. In addition to that it adds some complexity. I haven't found any real-world uses of this pattern yet, so I'm going to try to turn it off, and if nobody complains, remove the support altogether. If people do complain, we'll have to figure out how to make it work with minimization.
1 parent 7e9b64e commit e240310

15 files changed

+76
-122
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ namespace swift {
484484
ASTVerifierOverrideKind::NoOverride;
485485

486486
/// Enables merged associated type support, which might go away.
487-
bool RequirementMachineMergedAssociatedTypes = true;
487+
bool RequirementMachineMergedAssociatedTypes = false;
488488

489489
/// Enables dumping rewrite systems from the requirement machine.
490490
bool DumpRequirementMachine = false;

test/Generics/conditional_requirement_inference_unsupported.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift
2-
// RUN: not %target-swift-frontend -typecheck -debug-generic-signatures %s 2>&1 | %FileCheck %s
1+
// RUN: %target-typecheck-verify-swift -enable-requirement-machine-merged-associated-types
2+
// RUN: not %target-swift-frontend -typecheck -debug-generic-signatures %s -enable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
33

44
// A very elaborate invalid example (see comment in mergeP1AndP2())
55
struct G<T> {}
Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,25 @@
11
// RUN: %target-typecheck-verify-swift
22

3-
// Make sure the requirement machine can compute a confluent
4-
// completion in examples where we merge two associated types
5-
// with the same name, both having recursive conformance
6-
// requirements.
7-
8-
// Merged two cycles of length 1:
9-
//
10-
// P1 -> P1 -> P1 -> ...
11-
// P2 -> P2 -> P2 -> ...
123
protocol P1 {
134
associatedtype T : P1
145
}
156

167
protocol P2 {
17-
associatedtype T : P2
18-
}
19-
20-
struct S<T : P1 & P2> {}
21-
22-
// Merged a cycle of length 2 with a cycle of length 3
23-
//
24-
// P1a -> P1b -> P1a -> P1b -> P1a -> P1b -> ...
25-
// P2a -> P2b -> P2c -> P2a -> P2b -> P2c -> ...
26-
protocol P1a {
27-
associatedtype T : P1b
28-
}
29-
30-
protocol P1b {
31-
associatedtype T : P1a
8+
associatedtype T : P3
329
}
3310

34-
protocol P2a {
35-
associatedtype T : P2b
36-
}
37-
38-
protocol P2b {
39-
associatedtype T : P2c
40-
}
41-
42-
protocol P2c {
43-
associatedtype T : P2a
11+
protocol P3 {
12+
associatedtype T : P1
4413
}
4514

46-
struct SS<T : P1a & P2a> {}
15+
struct S<T : P1 & P2> {}
4716

48-
// Merged two cycles of length 1 via an inherited associated type
4917
protocol Base {
5018
associatedtype T : Base // expected-note {{'T' declared here}}
5119
}
5220

53-
// Base -> Base -> Base -> ...
54-
// Derived1 -> Derived1 -> Derived1 -> ...
5521
protocol Derived1 : Base {
5622
associatedtype T : Derived1 // expected-warning {{redeclaration of associated type 'T' from protocol 'Base' is better expressed as a 'where' clause on the protocol}}
5723
}
5824

59-
// Base -> Base -> Base -> ...
60-
// Derived2 -> Derived2 -> Derived2 -> ...
6125
protocol Derived2 : Base where T : Derived2 {}

test/Generics/unify_associated_types.swift

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
1+
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
22

33
struct Foo<A, B> {}
44

@@ -22,19 +22,15 @@ struct MergeTest<G : P1a & P2a> {}
2222

2323
// CHECK-LABEL: Adding generic signature <τ_0_0 where τ_0_0 : P1a, τ_0_0 : P2a> {
2424
// CHECK-LABEL: Rewrite system: {
25-
// CHECK: - τ_0_0.[P1a:T] => τ_0_0.[P1a&P2a:T]
26-
// CHECK: - τ_0_0.[P2a:T] => τ_0_0.[P1a&P2a:T]
27-
// CHECK: - τ_0_0.[P1a&P2a:T].[P1:X] => τ_0_0.[P1a&P2a:T].[P1&P2:X]
28-
// CHECK: - [P1a&P2a:T].[P1:X] => [P1a&P2a:T].[P1&P2:X]
29-
// CHECK: - [P1a&P2a:T].[P2:X] => [P1a&P2a:T].[P1&P2:X]
25+
// CHECK: - τ_0_0.[P2a:T] => τ_0_0.[P1a:T]
26+
// CHECK: - τ_0_0.[P1a:T].[P2] => τ_0_0.[P1a:T]
27+
// CHECK: - τ_0_0.[P1a:T].[P2:X] => τ_0_0.[P1a:T].[P1:X]
3028
// CHECK: }
3129
// CHECK: Rewrite loops: {
3230
// CHECK: }
3331
// CHECK: Property map: {
34-
// CHECK: [P1a:T] => { conforms_to: [P1] }
35-
// CHECK: [P2a:T] => { conforms_to: [P2] }
3632
// CHECK: τ_0_0 => { conforms_to: [P1a P2a] }
37-
// CHECK: [P1a&P2a:T] => { conforms_to: [P1 P2] }
33+
// CHECK: τ_0_0.[P1a:T] => { conforms_to: [P1 P2] }
3834
// CHECK: }
3935
// CHECK: }
4036

test/Generics/unify_concrete_types_1.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
1+
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
22

33
struct Foo<A, B> {}
44

@@ -28,5 +28,5 @@ struct MergeTest<G : P1 & P2> {
2828
// CHECK: [P1:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <[P1:Y1], [P1:Z1]>] }
2929
// CHECK: [P2:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <[P2:Y2], [P2:Z2]>] }
3030
// CHECK: τ_0_0 => { conforms_to: [P1 P2] }
31-
// CHECK: τ_0_0.[P1&P2:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <τ_0_0.[P1:Y1], τ_0_0.[P1:Z1]>] }
31+
// CHECK: τ_0_0.[P1:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <τ_0_0.[P1:Y1], τ_0_0.[P1:Z1]>] }
3232
// CHECK: }

test/Generics/unify_concrete_types_2.swift

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
1+
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
22

33
struct Foo<A, B> {}
44

@@ -29,11 +29,8 @@ struct MergeTest<G : P1a & P2a> {
2929

3030
// CHECK-LABEL: Adding generic signature <τ_0_0 where τ_0_0 : P1a, τ_0_0 : P2a> {
3131
// CHECK-LABEL: Rewrite system: {
32-
// CHECK: - τ_0_0.[P1a:T] => τ_0_0.[P1a&P2a:T]
33-
// CHECK: - τ_0_0.[P2a:T] => τ_0_0.[P1a&P2a:T]
34-
// CHECK: - [P1a&P2a:T].[P1:X] => [P1a&P2a:T].[P1&P2:X]
35-
// CHECK: - [P1a&P2a:T].[P2:X] => [P1a&P2a:T].[P1&P2:X]
36-
// CHECK: - τ_0_0.[P1a&P2a:T].[P2:Y2] => τ_0_0.[P1a&P2a:T].[P1:Y1]
37-
// CHECK: - τ_0_0.[P1a&P2a:T].[P2:Z2] => τ_0_0.[P1a&P2a:T].[P1:Z1]
32+
// CHECK: - τ_0_0.[P2a:T] => τ_0_0.[P1a:T]
33+
// CHECK: - τ_0_0.[P1a:T].[P2:Y2] => τ_0_0.[P1a:T].[P1:Y1]
34+
// CHECK: - τ_0_0.[P1a:T].[P2:Z2] => τ_0_0.[P1a:T].[P1:Z1]
3835
// CHECK: }
3936
// CHECK: }

test/Generics/unify_nested_types_1.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
1+
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
22

33
protocol P1 {
44
associatedtype T : P1
@@ -19,8 +19,8 @@ struct G<T : P1 & P2> {}
1919

2020
// CHECK-LABEL: Adding generic signature <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2> {
2121
// CHECK-LABEL: Rewrite system: {
22-
// CHECK: - τ_0_0.[P1&P2:T].[concrete: Int] => τ_0_0.[P1&P2:T]
23-
// CHECK: - [P1&P2:T].T => [P1&P2:T].[P1:T]
24-
// CHECK: - τ_0_0.[P1&P2:T].[P1:T] => τ_0_0.[P1&P2:T]
22+
// CHECK: - [P1:T].T => [P1:T].[P1:T]
23+
// CHECK: - τ_0_0.[P1:T].[concrete: Int] => τ_0_0.[P1:T]
24+
// CHECK: - τ_0_0.[P1:T].[P1:T] => τ_0_0.[P1:T]
2525
// CHECK: }
2626
// CHECK: }

test/Generics/unify_nested_types_2.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
1+
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
22

33
protocol P1 {
44
associatedtype T : P1
@@ -24,8 +24,8 @@ struct G<T : P1 & P2> {}
2424

2525
// CHECK-LABEL: Adding generic signature <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2> {
2626
// CHECK-LABEL: Rewrite system: {
27-
// CHECK: - τ_0_0.[P1&P2:T].[concrete: X<τ_0_0> with <τ_0_0.[P2:U]>] => τ_0_0.[P1&P2:T]
28-
// CHECK: - [P1&P2:T].T => [P1&P2:T].[P1:T]
29-
// CHECK: - τ_0_0.[P1&P2:T].[P1:T] => τ_0_0.[P1&P2:T]
27+
// CHECK: - [P1:T].T => [P1:T].[P1:T]
28+
// CHECK: - τ_0_0.[P1:T].[concrete: X<τ_0_0> with <τ_0_0.[P2:U]>] => τ_0_0.[P1:T]
29+
// CHECK: - τ_0_0.[P1:T].[P1:T] => τ_0_0.[P1:T]
3030
// CHECK: }
3131
// CHECK: }

test/Generics/unify_nested_types_3.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
1+
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
22

33
protocol P1 {
44
associatedtype T : P1
@@ -28,11 +28,11 @@ struct G<T : P2a & P3a> {}
2828

2929
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P2a, τ_0_0 : P3a>
3030
// CHECK-LABEL: Rewrite system: {
31-
// CHECK: - τ_0_0.[P2a&P3a:T].[concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] => τ_0_0.[P2a&P3a:T]
32-
// CHECK: - τ_0_0.[P2a&P3a:T].[P2:T].[concrete: X<τ_0_0> with <τ_0_0.[P3a:U].[P1:T]>] => τ_0_0.[P2a&P3a:T].[P2:T]
31+
// CHECK: - τ_0_0.[P2a:T].[concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] => τ_0_0.[P2a:T]
32+
// CHECK: - τ_0_0.[P2a:T].[P2:T].[concrete: X<τ_0_0> with <τ_0_0.[P3a:U].[P1:T]>] => τ_0_0.[P2a:T].[P2:T]
3333
// CHECK: }
3434
// CHECK-LABEL: Property map: {
35-
// CHECK: τ_0_0.[P2a&P3a:T] => { conforms_to: [P2] concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] }
36-
// CHECK: τ_0_0.[P2a&P3a:T].[P2:T] => { concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U].[P1:T]>] }
35+
// CHECK: τ_0_0.[P2a:T] => { conforms_to: [P2] concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] }
36+
// CHECK: τ_0_0.[P2a:T].[P2:T] => { concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U].[P1:T]>] }
3737
// CHECK: }
3838
// CHECK: }

test/Generics/unify_nested_types_4.swift

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
1+
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
22

33
protocol P1 {
44
associatedtype A : P1
@@ -42,23 +42,23 @@ struct G<T : P1 & P2> {}
4242

4343
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2>
4444
// CHECK-LABEL: Rewrite system: {
45-
// CHECK: - τ_0_0.[P1&P2:A].[concrete: S1 : P1] => τ_0_0.[P1&P2:A]
46-
// CHECK: - τ_0_0.[P1&P2:A].[P1:A] => τ_0_0.[P1&P2:A]
47-
// CHECK: - τ_0_0.[P1&P2:A].[P1:B].[concrete: S2] => τ_0_0.[P1&P2:A].[P1:B]
48-
// CHECK: - τ_0_0.[P1&P2:B].[concrete: S2 : P1] => τ_0_0.[P1&P2:B]
49-
// CHECK: - τ_0_0.[P1&P2:B].[P1:A] => τ_0_0.[P1&P2:B]
50-
// CHECK: - τ_0_0.[P1&P2:B].[P1:B].[concrete: S1] => τ_0_0.[P1&P2:B].[P1:B]
51-
// CHECK: - τ_0_0.[P1&P2:A].[P1:B].[concrete: S2 : P1] => τ_0_0.[P1&P2:A].[P1:B]
52-
// CHECK: - τ_0_0.[P1&P2:A].[P1:B].[P1:A] => τ_0_0.[P1&P2:A].[P1:B]
53-
// CHECK: - τ_0_0.[P1&P2:A].[P1:B].[P1:B] => τ_0_0.[P1&P2:A]
54-
// CHECK: - τ_0_0.[P1&P2:B].[P1:B].[concrete: S1 : P1] => τ_0_0.[P1&P2:B].[P1:B]
55-
// CHECK: - τ_0_0.[P1&P2:B].[P1:B].[P1:A] => τ_0_0.[P1&P2:B].[P1:B]
56-
// CHECK: - τ_0_0.[P1&P2:B].[P1:B].[P1:B] => τ_0_0.[P1&P2:B]
45+
// CHECK: - τ_0_0.[P1:A].[concrete: S1 : P1] => τ_0_0.[P1:A]
46+
// CHECK: - τ_0_0.[P1:A].[P1:A] => τ_0_0.[P1:A]
47+
// CHECK: - τ_0_0.[P1:A].[P1:B].[concrete: S2] => τ_0_0.[P1:A].[P1:B]
48+
// CHECK: - τ_0_0.[P1:B].[concrete: S2 : P1] => τ_0_0.[P1:B]
49+
// CHECK: - τ_0_0.[P1:B].[P1:A] => τ_0_0.[P1:B]
50+
// CHECK: - τ_0_0.[P1:B].[P1:B].[concrete: S1] => τ_0_0.[P1:B].[P1:B]
51+
// CHECK: - τ_0_0.[P1:A].[P1:B].[concrete: S2 : P1] => τ_0_0.[P1:A].[P1:B]
52+
// CHECK: - τ_0_0.[P1:A].[P1:B].[P1:A] => τ_0_0.[P1:A].[P1:B]
53+
// CHECK: - τ_0_0.[P1:A].[P1:B].[P1:B] => τ_0_0.[P1:A]
54+
// CHECK: - τ_0_0.[P1:B].[P1:B].[concrete: S1 : P1] => τ_0_0.[P1:B].[P1:B]
55+
// CHECK: - τ_0_0.[P1:B].[P1:B].[P1:A] => τ_0_0.[P1:B].[P1:B]
56+
// CHECK: - τ_0_0.[P1:B].[P1:B].[P1:B] => τ_0_0.[P1:B]
5757
// CHECK: }
5858
// CHECK-LABEL: Property map: {
59-
// CHECK: τ_0_0.[P1&P2:A] => { conforms_to: [P1] concrete_type: [concrete: S1] }
60-
// CHECK: τ_0_0.[P1&P2:B] => { conforms_to: [P1] concrete_type: [concrete: S2] }
61-
// CHECK: τ_0_0.[P1&P2:A].[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S2] }
62-
// CHECK: τ_0_0.[P1&P2:B].[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S1] }
59+
// CHECK: τ_0_0.[P1:A] => { conforms_to: [P1] concrete_type: [concrete: S1] }
60+
// CHECK: τ_0_0.[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S2] }
61+
// CHECK: τ_0_0.[P1:A].[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S2] }
62+
// CHECK: τ_0_0.[P1:B].[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S1] }
6363
// CHECK: }
6464
// CHECK: }

0 commit comments

Comments
 (0)