// RUN: %target-swift-frontend -typecheck -debug-generic-signatures %s 2>&1 | %FileCheck %s // CHECK-LABEL: main.(file).P1@ // CHECK: Requirement signature: protocol P1 { associatedtype A func f() -> A } // Recursion, and where clauses. // CHECK-LABEL: main.(file).P2@ // CHECK-NEXT: Requirement signature: protocol P2 { associatedtype A: P2 associatedtype B: P2 where Self.A.A == Self.B.A } // Simpler recursion // CHECK-LABEL: main.(file).P3@ // CHECK-NEXT: Requirement signature: protocol P3 { associatedtype A: P3 } // CHECK-LABEL: StructDecl name=Basic // CHECK: (normal_conformance type="Basic" protocol="P1" // CHECK-NEXT: (assoc_type req="A" type="Int") // CHECK-NEXT: (value req="f()" witness="main.(file).Basic.f()@{{.*}}") struct Basic: P1 { typealias A = Int func f() -> Int { fatalError() } } // Recursive conformances should have finite output. // CHECK-LABEL: StructDecl name=Recur // CHECK-NEXT: (builtin_conformance type="Recur" protocol="Copyable"{{.*}}) // CHECK-NEXT: (builtin_conformance type="Recur" protocol="Escapable"{{.*}}) // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2" // CHECK-NEXT: (assoc_type req="A" type="Recur") // CHECK-NEXT: (assoc_type req="B" type="Recur") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="Recur" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="Recur" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2"{{.*}}
)) // CHECK-NEXT: (assoc_conformance type="Self.B" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2"{{.*}}
))) struct Recur: P2 { typealias A = Recur typealias B = Recur } // The full information about a conformance doesn't need to be printed twice. // CHECK-LABEL: StructDecl name=NonRecur // CHECK-NEXT: (builtin_conformance type="NonRecur" protocol="Copyable"{{.*}}) // CHECK-NEXT: (builtin_conformance type="NonRecur" protocol="Escapable"{{.*}}) // CHECK-NEXT: (normal_conformance type="NonRecur" protocol="P2" // CHECK-NEXT: (assoc_type req="A" type="Recur") // CHECK-NEXT: (assoc_type req="B" type="Recur") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="NonRecur" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="NonRecur" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2" // CHECK-NEXT: (assoc_type req="A" type="Recur") // CHECK-NEXT: (assoc_type req="B" type="Recur") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="Recur" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="Recur" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2"{{.*}}
)) // CHECK-NEXT: (assoc_conformance type="Self.B" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2"{{.*}}
)))) // CHECK-NEXT: (assoc_conformance type="Self.B" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2"{{.*}}
))) struct NonRecur: P2 { typealias A = Recur typealias B = Recur } // Conditional conformance. // CHECK: Generic signature: // CHECK-NEXT: Canonical generic signature: <τ_0_0> // CHECK-LABEL: ExtensionDecl line={{.*}} base=Generic struct Generic {} // CHECK-LABEL: ExtensionDecl line={{.*}} base=Generic // CHECK-NEXT: (normal_conformance type="Generic" protocol="P1" // CHECK-NEXT: (assoc_type req="A" type="T") // CHECK-NEXT: (value req="f()" witness="main.(file).Generic extension.f()@{{.*}}") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="Generic" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="Generic" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="Copyable" // CHECK-NEXT: (abstract_conformance type="T" protocol="Copyable")) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="Escapable" // CHECK-NEXT: (abstract_conformance type="T" protocol="Escapable")) // CHECK-NEXT: (requirement "T" conforms_to "P1")) extension Generic: P1 where T: P1 { typealias A = T func f() -> T { fatalError() } } // Satisfying associated types with requirements with generic params // CHECK: Generic signature: // CHECK-NEXT: Canonical generic signature: <τ_0_0, τ_0_1> // CHECK-LABEL: ExtensionDecl line={{.*}} base=Super class Super {} // CHECK-LABEL: ExtensionDecl line={{.*}} base=Super // CHECK-NEXT: (normal_conformance type="Super" protocol="P2" // CHECK-NEXT: (assoc_type req="A" type="T") // CHECK-NEXT: (assoc_type req="B" type="T") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="Super" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="Super" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P2" // CHECK-NEXT: (abstract_conformance type="T" protocol="P2")) // CHECK-NEXT: (assoc_conformance type="Self.B" proto="P2" // CHECK-NEXT: (abstract_conformance type="T" protocol="P2")) // CHECK-NEXT: (requirement "T" conforms_to "P2") // CHECK-NEXT: (requirement "U" conforms_to "P2")) extension Super: P2 where T: P2, U: P2 { typealias A = T typealias B = T } // Inherited/specialized conformances. // CHECK-LABEL: ClassDecl name=Sub // CHECK-NEXT: (builtin_conformance type="Sub" protocol="Copyable"{{.*}}) // CHECK-NEXT: (builtin_conformance type="Sub" protocol="Escapable"{{.*}}) // CHECK-NEXT: (inherited_conformance type="Sub" protocol="P2" // CHECK-NEXT: (specialized_conformance type="Super" protocol="P2" // CHECK-NEXT: (substitution_map generic_signature= // CHECK-NEXT: (substitution T -> // CHECK-NEXT: (struct_type decl="main.(file).NonRecur@{{.*}}")) // CHECK-NEXT: (substitution U -> // CHECK-NEXT: (struct_type decl="main.(file).Recur@{{.*}}")) // CHECK-NEXT: (conformance type="T" // CHECK-NEXT: (normal_conformance type="NonRecur" protocol="P2" // CHECK-NEXT: (assoc_type req="A" type="Recur") // CHECK-NEXT: (assoc_type req="B" type="Recur") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="NonRecur" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="NonRecur" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2" // CHECK-NEXT: (assoc_type req="A" type="Recur") // CHECK-NEXT: (assoc_type req="B" type="Recur") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="Recur" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="Recur" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2"{{.*}}
)) // CHECK-NEXT: (assoc_conformance type="Self.B" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2"{{.*}}
)))) // CHECK-NEXT: (assoc_conformance type="Self.B" proto="P2" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2"{{.*}}
)))) // CHECK-NEXT: (conformance type="U" // CHECK-NEXT: (normal_conformance type="Recur" protocol="P2"{{.*}}
))) // CHECK-NEXT: () // CHECK-NEXT: (normal_conformance type="Super" protocol="P2" // CHECK-NEXT: (assoc_type req="A" type="T") // CHECK-NEXT: (assoc_type req="B" type="T") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="Super" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="Super" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P2" // CHECK-NEXT: (abstract_conformance type="T" protocol="P2")) // CHECK-NEXT: (assoc_conformance type="Self.B" proto="P2" // CHECK-NEXT: (abstract_conformance type="T" protocol="P2")) // CHECK-NEXT: (requirement "T" conforms_to "P2") // CHECK-NEXT: (requirement "U" conforms_to "P2")))) class Sub: Super {} // Specialization of a recursive conformance should be okay: recursion detection // should work through SubstitutionMaps. // CHECK-LABEL: StructDecl name=RecurGeneric // CHECK-NEXT: (builtin_conformance type="RecurGeneric" protocol="Copyable"{{.*}}) // CHECK-NEXT: (builtin_conformance type="RecurGeneric" protocol="Escapable"{{.*}}) // CHECK-NEXT: (normal_conformance type="RecurGeneric" protocol="P3" // CHECK-NEXT: (assoc_type req="A" type="RecurGeneric") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="RecurGeneric" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="RecurGeneric" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P3" // CHECK-NEXT: (normal_conformance type="RecurGeneric" protocol="P3"{{.*}}
))) struct RecurGeneric: P3 { typealias A = RecurGeneric } // CHECK-LABEL: StructDecl name=Specialize // CHECK-NEXT: (builtin_conformance type="Specialize" protocol="Copyable"{{.*}}) // CHECK-NEXT: (builtin_conformance type="Specialize" protocol="Escapable"{{.*}}) // CHECK-NEXT: (normal_conformance type="Specialize" protocol="P3" // CHECK-NEXT: (assoc_type req="A" type="RecurGeneric") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="Specialize" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="Specialize" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P3" // CHECK-NEXT: (specialized_conformance type="Specialize.A" protocol="P3" // CHECK-NEXT: (substitution_map generic_signature= // CHECK-NEXT: (substitution T -> // CHECK-NEXT: (struct_type decl="main.(file).Specialize@{{.*}}")) // CHECK-NEXT: (conformance type="T" // CHECK-NEXT: (normal_conformance type="Specialize" protocol="P3"{{.*}}
))) // CHECK-NEXT: (normal_conformance type="RecurGeneric" protocol="P3" // CHECK-NEXT: (assoc_type req="A" type="RecurGeneric") // CHECK-NEXT: (assoc_conformance type="Self" proto="Copyable" // CHECK-NEXT: (builtin_conformance type="RecurGeneric" protocol="Copyable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self" proto="Escapable" // CHECK-NEXT: (builtin_conformance type="RecurGeneric" protocol="Escapable"{{.*}})) // CHECK-NEXT: (assoc_conformance type="Self.A" proto="P3" // CHECK-NEXT: (normal_conformance type="RecurGeneric" protocol="P3"{{.*}}
)))))) struct Specialize: P3 { typealias A = RecurGeneric }