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.
This commit is contained in:
Slava Pestov
2022-01-20 22:31:09 -05:00
parent 7e9b64ecf7
commit e24031012f
15 changed files with 77 additions and 123 deletions

View File

@@ -484,7 +484,7 @@ namespace swift {
ASTVerifierOverrideKind::NoOverride;
/// Enables merged associated type support, which might go away.
bool RequirementMachineMergedAssociatedTypes = true;
bool RequirementMachineMergedAssociatedTypes = false;
/// Enables dumping rewrite systems from the requirement machine.
bool DumpRequirementMachine = false;

View File

@@ -1,5 +1,5 @@
// RUN: %target-typecheck-verify-swift
// RUN: not %target-swift-frontend -typecheck -debug-generic-signatures %s 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -enable-requirement-machine-merged-associated-types
// RUN: not %target-swift-frontend -typecheck -debug-generic-signatures %s -enable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
// A very elaborate invalid example (see comment in mergeP1AndP2())
struct G<T> {}

View File

@@ -1,61 +1,25 @@
// RUN: %target-typecheck-verify-swift
// Make sure the requirement machine can compute a confluent
// completion in examples where we merge two associated types
// with the same name, both having recursive conformance
// requirements.
// Merged two cycles of length 1:
//
// P1 -> P1 -> P1 -> ...
// P2 -> P2 -> P2 -> ...
protocol P1 {
associatedtype T : P1
}
protocol P2 {
associatedtype T : P2
associatedtype T : P3
}
protocol P3 {
associatedtype T : P1
}
struct S<T : P1 & P2> {}
// Merged a cycle of length 2 with a cycle of length 3
//
// P1a -> P1b -> P1a -> P1b -> P1a -> P1b -> ...
// P2a -> P2b -> P2c -> P2a -> P2b -> P2c -> ...
protocol P1a {
associatedtype T : P1b
}
protocol P1b {
associatedtype T : P1a
}
protocol P2a {
associatedtype T : P2b
}
protocol P2b {
associatedtype T : P2c
}
protocol P2c {
associatedtype T : P2a
}
struct SS<T : P1a & P2a> {}
// Merged two cycles of length 1 via an inherited associated type
protocol Base {
associatedtype T : Base // expected-note {{'T' declared here}}
}
// Base -> Base -> Base -> ...
// Derived1 -> Derived1 -> Derived1 -> ...
protocol Derived1 : Base {
associatedtype T : Derived1 // expected-warning {{redeclaration of associated type 'T' from protocol 'Base' is better expressed as a 'where' clause on the protocol}}
}
// Base -> Base -> Base -> ...
// Derived2 -> Derived2 -> Derived2 -> ...
protocol Derived2 : Base where T : Derived2 {}

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
struct Foo<A, B> {}
@@ -22,19 +22,15 @@ struct MergeTest<G : P1a & P2a> {}
// CHECK-LABEL: Adding generic signature <τ_0_0 where τ_0_0 : P1a, τ_0_0 : P2a> {
// CHECK-LABEL: Rewrite system: {
// CHECK: - τ_0_0.[P1a:T] => τ_0_0.[P1a&P2a:T]
// CHECK: - τ_0_0.[P2a:T] => τ_0_0.[P1a&P2a:T]
// CHECK: - τ_0_0.[P1a&P2a:T].[P1:X] => τ_0_0.[P1a&P2a:T].[P1&P2:X]
// CHECK: - [P1a&P2a:T].[P1:X] => [P1a&P2a:T].[P1&P2:X]
// CHECK: - [P1a&P2a:T].[P2:X] => [P1a&P2a:T].[P1&P2:X]
// CHECK: - τ_0_0.[P2a:T] => τ_0_0.[P1a:T]
// CHECK: - τ_0_0.[P1a:T].[P2] => τ_0_0.[P1a:T]
// CHECK: - τ_0_0.[P1a:T].[P2:X] => τ_0_0.[P1a:T].[P1:X]
// CHECK: }
// CHECK: Rewrite loops: {
// CHECK: }
// CHECK: Property map: {
// CHECK: [P1a:T] => { conforms_to: [P1] }
// CHECK: [P2a:T] => { conforms_to: [P2] }
// CHECK: τ_0_0 => { conforms_to: [P1a P2a] }
// CHECK: [P1a&P2a:T] => { conforms_to: [P1 P2] }
// CHECK: τ_0_0.[P1a:T] => { conforms_to: [P1 P2] }
// CHECK: }
// CHECK: }

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
struct Foo<A, B> {}
@@ -28,5 +28,5 @@ struct MergeTest<G : P1 & P2> {
// CHECK: [P1:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <[P1:Y1], [P1:Z1]>] }
// CHECK: [P2:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <[P2:Y2], [P2:Z2]>] }
// CHECK: τ_0_0 => { conforms_to: [P1 P2] }
// CHECK: τ_0_0.[P1&P2:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <τ_0_0.[P1:Y1], τ_0_0.[P1:Z1]>] }
// CHECK: τ_0_0.[P1:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <τ_0_0.[P1:Y1], τ_0_0.[P1:Z1]>] }
// CHECK: }

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
struct Foo<A, B> {}
@@ -29,11 +29,8 @@ struct MergeTest<G : P1a & P2a> {
// CHECK-LABEL: Adding generic signature <τ_0_0 where τ_0_0 : P1a, τ_0_0 : P2a> {
// CHECK-LABEL: Rewrite system: {
// CHECK: - τ_0_0.[P1a:T] => τ_0_0.[P1a&P2a:T]
// CHECK: - τ_0_0.[P2a:T] => τ_0_0.[P1a&P2a:T]
// CHECK: - [P1a&P2a:T].[P1:X] => [P1a&P2a:T].[P1&P2:X]
// CHECK: - [P1a&P2a:T].[P2:X] => [P1a&P2a:T].[P1&P2:X]
// CHECK: - τ_0_0.[P1a&P2a:T].[P2:Y2] => τ_0_0.[P1a&P2a:T].[P1:Y1]
// CHECK: - τ_0_0.[P1a&P2a:T].[P2:Z2] => τ_0_0.[P1a&P2a:T].[P1:Z1]
// CHECK: - τ_0_0.[P2a:T] => τ_0_0.[P1a:T]
// CHECK: - τ_0_0.[P1a:T].[P2:Y2] => τ_0_0.[P1a:T].[P1:Y1]
// CHECK: - τ_0_0.[P1a:T].[P2:Z2] => τ_0_0.[P1a:T].[P1:Z1]
// CHECK: }
// CHECK: }

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
protocol P1 {
associatedtype T : P1
@@ -19,8 +19,8 @@ struct G<T : P1 & P2> {}
// CHECK-LABEL: Adding generic signature <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2> {
// CHECK-LABEL: Rewrite system: {
// CHECK: - τ_0_0.[P1&P2:T].[concrete: Int] => τ_0_0.[P1&P2:T]
// CHECK: - [P1&P2:T].T => [P1&P2:T].[P1:T]
// CHECK: - τ_0_0.[P1&P2:T].[P1:T] => τ_0_0.[P1&P2:T]
// CHECK: - [P1:T].T => [P1:T].[P1:T]
// CHECK: - τ_0_0.[P1:T].[concrete: Int] => τ_0_0.[P1:T]
// CHECK: - τ_0_0.[P1:T].[P1:T] => τ_0_0.[P1:T]
// CHECK: }
// CHECK: }

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
protocol P1 {
associatedtype T : P1
@@ -24,8 +24,8 @@ struct G<T : P1 & P2> {}
// CHECK-LABEL: Adding generic signature <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2> {
// CHECK-LABEL: Rewrite system: {
// CHECK: - τ_0_0.[P1&P2:T].[concrete: X<τ_0_0> with <τ_0_0.[P2:U]>] => τ_0_0.[P1&P2:T]
// CHECK: - [P1&P2:T].T => [P1&P2:T].[P1:T]
// CHECK: - τ_0_0.[P1&P2:T].[P1:T] => τ_0_0.[P1&P2:T]
// CHECK: - [P1:T].T => [P1:T].[P1:T]
// CHECK: - τ_0_0.[P1:T].[concrete: X<τ_0_0> with <τ_0_0.[P2:U]>] => τ_0_0.[P1:T]
// CHECK: - τ_0_0.[P1:T].[P1:T] => τ_0_0.[P1:T]
// CHECK: }
// CHECK: }

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
protocol P1 {
associatedtype T : P1
@@ -28,11 +28,11 @@ struct G<T : P2a & P3a> {}
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P2a, τ_0_0 : P3a>
// CHECK-LABEL: Rewrite system: {
// CHECK: - τ_0_0.[P2a&P3a:T].[concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] => τ_0_0.[P2a&P3a:T]
// 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]
// CHECK: - τ_0_0.[P2a:T].[concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] => τ_0_0.[P2a:T]
// CHECK: - τ_0_0.[P2a:T].[P2:T].[concrete: X<τ_0_0> with <τ_0_0.[P3a:U].[P1:T]>] => τ_0_0.[P2a:T].[P2:T]
// CHECK: }
// CHECK-LABEL: Property map: {
// CHECK: τ_0_0.[P2a&P3a:T] => { conforms_to: [P2] concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] }
// CHECK: τ_0_0.[P2a&P3a:T].[P2:T] => { concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U].[P1:T]>] }
// CHECK: τ_0_0.[P2a:T] => { conforms_to: [P2] concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] }
// CHECK: τ_0_0.[P2a:T].[P2:T] => { concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U].[P1:T]>] }
// CHECK: }
// CHECK: }

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
protocol P1 {
associatedtype A : P1
@@ -42,23 +42,23 @@ struct G<T : P1 & P2> {}
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2>
// CHECK-LABEL: Rewrite system: {
// CHECK: - τ_0_0.[P1&P2:A].[concrete: S1 : P1] => τ_0_0.[P1&P2:A]
// CHECK: - τ_0_0.[P1&P2:A].[P1:A] => τ_0_0.[P1&P2:A]
// CHECK: - τ_0_0.[P1&P2:A].[P1:B].[concrete: S2] => τ_0_0.[P1&P2:A].[P1:B]
// CHECK: - τ_0_0.[P1&P2:B].[concrete: S2 : P1] => τ_0_0.[P1&P2:B]
// CHECK: - τ_0_0.[P1&P2:B].[P1:A] => τ_0_0.[P1&P2:B]
// CHECK: - τ_0_0.[P1&P2:B].[P1:B].[concrete: S1] => τ_0_0.[P1&P2:B].[P1:B]
// CHECK: - τ_0_0.[P1&P2:A].[P1:B].[concrete: S2 : P1] => τ_0_0.[P1&P2:A].[P1:B]
// CHECK: - τ_0_0.[P1&P2:A].[P1:B].[P1:A] => τ_0_0.[P1&P2:A].[P1:B]
// CHECK: - τ_0_0.[P1&P2:A].[P1:B].[P1:B] => τ_0_0.[P1&P2:A]
// CHECK: - τ_0_0.[P1&P2:B].[P1:B].[concrete: S1 : P1] => τ_0_0.[P1&P2:B].[P1:B]
// CHECK: - τ_0_0.[P1&P2:B].[P1:B].[P1:A] => τ_0_0.[P1&P2:B].[P1:B]
// CHECK: - τ_0_0.[P1&P2:B].[P1:B].[P1:B] => τ_0_0.[P1&P2:B]
// CHECK: - τ_0_0.[P1:A].[concrete: S1 : P1] => τ_0_0.[P1:A]
// CHECK: - τ_0_0.[P1:A].[P1:A] => τ_0_0.[P1:A]
// CHECK: - τ_0_0.[P1:A].[P1:B].[concrete: S2] => τ_0_0.[P1:A].[P1:B]
// CHECK: - τ_0_0.[P1:B].[concrete: S2 : P1] => τ_0_0.[P1:B]
// CHECK: - τ_0_0.[P1:B].[P1:A] => τ_0_0.[P1:B]
// CHECK: - τ_0_0.[P1:B].[P1:B].[concrete: S1] => τ_0_0.[P1:B].[P1:B]
// CHECK: - τ_0_0.[P1:A].[P1:B].[concrete: S2 : P1] => τ_0_0.[P1:A].[P1:B]
// CHECK: - τ_0_0.[P1:A].[P1:B].[P1:A] => τ_0_0.[P1:A].[P1:B]
// CHECK: - τ_0_0.[P1:A].[P1:B].[P1:B] => τ_0_0.[P1:A]
// CHECK: - τ_0_0.[P1:B].[P1:B].[concrete: S1 : P1] => τ_0_0.[P1:B].[P1:B]
// CHECK: - τ_0_0.[P1:B].[P1:B].[P1:A] => τ_0_0.[P1:B].[P1:B]
// CHECK: - τ_0_0.[P1:B].[P1:B].[P1:B] => τ_0_0.[P1:B]
// CHECK: }
// CHECK-LABEL: Property map: {
// CHECK: τ_0_0.[P1&P2:A] => { conforms_to: [P1] concrete_type: [concrete: S1] }
// CHECK: τ_0_0.[P1&P2:B] => { conforms_to: [P1] concrete_type: [concrete: S2] }
// CHECK: τ_0_0.[P1&P2:A].[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S2] }
// CHECK: τ_0_0.[P1&P2:B].[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S1] }
// CHECK: τ_0_0.[P1:A] => { conforms_to: [P1] concrete_type: [concrete: S1] }
// CHECK: τ_0_0.[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S2] }
// CHECK: τ_0_0.[P1:A].[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S2] }
// CHECK: τ_0_0.[P1:B].[P1:B] => { conforms_to: [P1] concrete_type: [concrete: S1] }
// CHECK: }
// CHECK: }

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
// Note: The GSB fails this test, because it doesn't implement unification of
// superclass type constructor arguments.
@@ -30,16 +30,12 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2>
// CHECK-NEXT: Rewrite system: {
// CHECK: - τ_0_0.[P1&P2:X].[superclass: Generic<τ_0_0, String, τ_0_1> with <τ_0_0.[P2:A2], τ_0_0.[P2:B2]>] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P1&P2:X].[superclass: Generic<Int, τ_0_0, τ_0_1> with <τ_0_0.[P1:A1], τ_0_0.[P1:B1]>] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.X => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P2:X] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - [P1:X].[layout: _NativeClass] => [P1:X]
// CHECK-NEXT: - [P2:X].[layout: _NativeClass] => [P2:X]
// CHECK-NEXT: - τ_0_0.[P1&P2:X].[layout: _NativeClass] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P2:A2].[concrete: Int] => τ_0_0.[P2:A2]
// CHECK: - τ_0_0.[P2:X] => τ_0_0.[P1:X]
// CHECK: - τ_0_0.[P2:A2].[concrete: Int] => τ_0_0.[P2:A2]
// CHECK-NEXT: - τ_0_0.[P1:A1].[concrete: String] => τ_0_0.[P1:A1]
// CHECK-NEXT: - τ_0_0.[P2:B2] => τ_0_0.[P1:B1]
// CHECK-NEXT: - τ_0_0.B2 => τ_0_0.[P1:B1]
// CHECK: - τ_0_0.[P1:X].[superclass: Generic<τ_0_0, String, τ_0_1> with <τ_0_0.[P2:A2], τ_0_0.[P1:B1]>] => τ_0_0.[P1:X]
// CHECK: }
// CHECK: Property map: {
// CHECK-NEXT: [P1] => { conforms_to: [P1] }
@@ -47,7 +43,7 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Generic<Int, τ_0_0, τ_0_1> with <[P1:A1], [P1:B1]>] }
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Generic<τ_0_0, String, τ_0_1> with <[P2:A2], [P2:B2]>] }
// CHECK-NEXT: τ_0_0 => { conforms_to: [P1 P2] }
// CHECK-NEXT: τ_0_0.[P1&P2:X] => { layout: _NativeClass superclass: [superclass: Generic<τ_0_0, String, τ_0_1> with <τ_0_0.[P2:A2], τ_0_0.[P1:B1]>] }
// CHECK-NEXT: τ_0_0.[P2:A2] => { concrete_type: [concrete: Int] }
// CHECK-NEXT: τ_0_0.[P1:A1] => { concrete_type: [concrete: String] }
// CHECK-NEXT: τ_0_0.[P1:X] => { layout: _NativeClass superclass: [superclass: Generic<τ_0_0, String, τ_0_1> with <τ_0_0.[P2:A2], τ_0_0.[P1:B1]>] }
// CHECK-NEXT: }

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
// Note: The GSB fails this test, because it doesn't implement unification of
// superclass type constructor arguments.
@@ -32,18 +32,14 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2>
// CHECK-NEXT: Rewrite system: {
// CHECK: - τ_0_0.[P1&P2:X].[superclass: Generic<τ_0_0, String, τ_0_1> with <τ_0_0.[P2:A2], τ_0_0.[P2:B2]>] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P1&P2:X].[superclass: Derived<τ_0_0, τ_0_1> with <τ_0_0.[P1:A1], τ_0_0.[P1:B1]>] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.X => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P2:X] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - [P1:X].[layout: _NativeClass] => [P1:X]
// CHECK-NEXT: - [P2:X].[layout: _NativeClass] => [P2:X]
// CHECK-NEXT: - τ_0_0.[P1&P2:X].[layout: _NativeClass] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P2:A2].[concrete: Int] => τ_0_0.[P2:A2]
// CHECK: - τ_0_0.[P2:X] => τ_0_0.[P1:X]
// CHECK: - [P1:X].[layout: _NativeClass] => [P1:X]
// CHECK: - [P2:X].[layout: _NativeClass] => [P2:X]
// CHECK: - τ_0_0.[P2:A2].[concrete: Int] => τ_0_0.[P2:A2]
// CHECK-NEXT: - τ_0_0.[P1:A1].[concrete: String] => τ_0_0.[P1:A1]
// CHECK-NEXT: - τ_0_0.[P2:B2] => τ_0_0.[P1:B1]
// CHECK-NEXT: - τ_0_0.B2 => τ_0_0.[P1:B1]
// CHECK-NEXT: - τ_0_0.[P1&P2:X].[superclass: Generic<τ_0_0, String, τ_0_1> with <τ_0_0.[P2:A2], τ_0_0.[P1:B1]>] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P1:X].[superclass: Generic<τ_0_0, String, τ_0_1> with <τ_0_0.[P2:A2], τ_0_0.[P1:B1]>] => τ_0_0.[P1:X]
// CHECK-NEXT: }
// CHECK: Property map: {
// CHECK-NEXT: [P1] => { conforms_to: [P1] }
@@ -51,7 +47,7 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0, τ_0_1> with <[P1:A1], [P1:B1]>] }
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Generic<τ_0_0, String, τ_0_1> with <[P2:A2], [P2:B2]>] }
// CHECK-NEXT: τ_0_0 => { conforms_to: [P1 P2] }
// CHECK-NEXT: τ_0_0.[P1&P2:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0, τ_0_1> with <τ_0_0.[P1:A1], τ_0_0.[P1:B1]>] }
// CHECK-NEXT: τ_0_0.[P2:A2] => { concrete_type: [concrete: Int] }
// CHECK-NEXT: τ_0_0.[P1:A1] => { concrete_type: [concrete: String] }
// CHECK-NEXT: τ_0_0.[P1:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0, τ_0_1> with <τ_0_0.[P1:A1], τ_0_0.[P1:B1]>] }
// CHECK-NEXT: }

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -dump-requirement-machine 2>&1 | %FileCheck %s
// RUN: %target-typecheck-verify-swift -dump-requirement-machine -disable-requirement-machine-merged-associated-types 2>&1 | %FileCheck %s
// Note: The GSB fails this test, because it doesn't implement unification of
// superclass type constructor arguments.
@@ -35,13 +35,12 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2>
// CHECK-NEXT: Rewrite system: {
// CHECK: - τ_0_0.[P1&P2:X].[superclass: Derived<τ_0_0> with <τ_0_0.[P2:A2]>] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P1&P2:X].[superclass: Base<τ_0_0> with <τ_0_0.[P1:A1]>] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.X => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P2:X] => τ_0_0.[P1&P2:X]
// CHECK: - [P1:X].[superclass: Base<τ_0_0> with <[P1:A1]>] => [P1:X] [explicit]
// CHECK: - [P2:X].[superclass: Derived<τ_0_0> with <[P2:A2]>] => [P2:X] [explicit]
// CHECK: - τ_0_0.[P2:X] => τ_0_0.[P1:X]
// CHECK: - τ_0_0.[P1:X].[superclass: Derived<τ_0_0> with <τ_0_0.[P2:A2]>] => τ_0_0.[P1:X]
// CHECK-NEXT: - [P1:X].[layout: _NativeClass] => [P1:X]
// CHECK-NEXT: - [P2:X].[layout: _NativeClass] => [P2:X]
// CHECK-NEXT: - τ_0_0.[P1&P2:X].[layout: _NativeClass] => τ_0_0.[P1&P2:X]
// CHECK-NEXT: - τ_0_0.[P2:A2].[Q:T] => τ_0_0.[P1:A1]
// CHECK-NEXT: }
// CHECK: Property map: {
@@ -52,5 +51,5 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
// CHECK-NEXT: [P2:A2] => { conforms_to: [Q] }
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0> with <[P2:A2]>] }
// CHECK-NEXT: τ_0_0 => { conforms_to: [P1 P2] }
// CHECK-NEXT: τ_0_0.[P1&P2:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0> with <τ_0_0.[P2:A2]>] }
// CHECK-NEXT: τ_0_0.[P1:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0> with <τ_0_0.[P2:A2]>] }
// CHECK-NEXT: }

View File

@@ -19,7 +19,7 @@ protocol First {
}
protocol Second {
associatedtype Assoc : Second
associatedtype Assoc : Second where Assoc.Assoc.Assoc == Self
}
struct OuterFirst<A : First, B : First> {

View File

@@ -9,7 +9,7 @@ protocol First {
}
protocol Second {
associatedtype Assoc : Second
associatedtype Assoc : Second where Assoc.Assoc.Assoc == Self
}
struct OuterFirst<A : First, B : First> {
@@ -69,11 +69,17 @@ struct FS1: First, Second {
}
struct FS2: First, Second {
typealias Assoc = FS1
typealias Assoc = FS3
func Assoc(_ x: Int) -> Int { return x / 2 }
}
struct FS3: First, Second {
typealias Assoc = FS1
func Assoc(_ x: Int) -> Int { return x * 2 }
}
public func test() {
roundTripType(OuterFirst<F1,F2>.self)
roundTripType(OuterBoth<FS1,FS2>.self)