// RUN: %target-typecheck-verify-swift -typecheck %s -verify // RUN: %target-typecheck-verify-swift -typecheck -debug-generic-signatures %s > %t.dump 2>&1 // RUN: %FileCheck %s < %t.dump protocol P1 { func p1() } protocol P2 : P1 { } struct X1 { func getT() -> T { } } class X2 { func getT() -> T { } } class X3 { } struct X4 { func getT() -> T { } } struct X5 { } // Infer protocol requirements from the parameter type of a generic function. func inferFromParameterType(_ x: X1) { x.getT().p1() } // Infer protocol requirements from the return type of a generic function. func inferFromReturnType(_ x: T) -> X1 { x.p1() } // Infer protocol requirements from the superclass of a generic parameter. func inferFromSuperclass>(_ t: T, u: U) -> T { t.p1() } // Infer protocol requirements from the parameter type of a constructor. struct InferFromConstructor { init (x : X1) { x.getT().p1() } } // Don't infer requirements for outer generic parameters. class Fox : P1 { func p1() {} } class Box { // CHECK-LABEL: .unpack@ // CHECK-NEXT: Requirements: // CHECK-NEXT: τ_0_0 : Fox [explicit] func unpack(_ x: X1) {} } // ---------------------------------------------------------------------------- // Superclass requirements // ---------------------------------------------------------------------------- // Compute meet of two superclass requirements correctly. class Carnivora {} class Canidae : Carnivora {} struct U {} struct V {} // CHECK-LABEL: .inferSuperclassRequirement1@ // CHECK-NEXT: Requirements: // CHECK-NEXT: τ_0_0 : Canidae func inferSuperclassRequirement1(_ v: V) {} // CHECK-LABEL: .inferSuperclassRequirement2@ // CHECK-NEXT: Requirements: // CHECK-NEXT: τ_0_0 : Canidae func inferSuperclassRequirement2(_ v: U) {} // ---------------------------------------------------------------------------- // Same-type requirements // ---------------------------------------------------------------------------- protocol P3 { associatedtype P3Assoc : P2 } protocol P4 { associatedtype P4Assoc : P1 } protocol PCommonAssoc1 { associatedtype CommonAssoc } protocol PCommonAssoc2 { associatedtype CommonAssoc } protocol PAssoc { associatedtype Assoc } struct Model_P3_P4_Eq where T.P3Assoc == U.P4Assoc {} // CHECK-LABEL: .inferSameType1@ // CHECK-NEXT: Requirements: // CHECK-NEXT: τ_0_0 : P3 [inferred @ {{.*}}:32] // CHECK-NEXT: τ_0_1 : P4 [inferred @ {{.*}}:32] // CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [protocol @ {{.*}}:32] // CHECK-NEXT: τ_0_0[.P3].P3Assoc : P2 [protocol @ {{.*}}:32] func inferSameType1(_ x: Model_P3_P4_Eq) { } // CHECK-LABEL: .inferSameType2@ // CHECK-NEXT: Requirements: // CHECK-NEXT: τ_0_0 : P3 [inferred] // CHECK-NEXT: τ_0_1 : P4 [inferred] // CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [protocol @ {{.*}}requirement_inference.swift:{{.*}}:25] // CHECK-NEXT: τ_0_0[.P3].P3Assoc : P2 [protocol @ {{.*}}requirement_inference.swift:{{.*}}:25] // CHECK-NEXT: τ_0_0[.P3].P3Assoc == τ_0_1[.P4].P4Assoc [explicit] func inferSameType2(_: T, _: U) where U.P4Assoc : P2, T.P3Assoc == U.P4Assoc {} // CHECK-LABEL: .inferSameType3@ // CHECK-NEXT: Requirements: // CHECK-NEXT: τ_0_0 : PCommonAssoc1 [inferred] // CHECK-NEXT: τ_0_0 : PCommonAssoc2 [explicit @ {{.*}}requirement_inference.swift:{{.*}}:76] // CHECK-NEXT: τ_0_0[.PCommonAssoc1].CommonAssoc : P1 [explicit @ {{.*}}requirement_inference.swift:{{.*}}:68] // CHECK-NEXT: Potential archetypes func inferSameType3(_: T) where T.CommonAssoc : P1, T : PCommonAssoc2 {} protocol P5 { associatedtype Element } protocol P6 { associatedtype AssocP6 : P5 } protocol P7 : P6 { associatedtype AssocP7: P6 } // CHECK-LABEL: P7.nestedSameType1()@ // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P7, τ_0_0.AssocP6.Element : P6, τ_0_0.AssocP6.Element == τ_0_0.AssocP7.AssocP6.Element> extension P7 where AssocP6.Element : P6, AssocP7.AssocP6.Element : P6, AssocP6.Element == AssocP7.AssocP6.Element { func nestedSameType1() { } } protocol P8 { associatedtype A associatedtype B } protocol P9 : P8 { associatedtype A associatedtype B } protocol P10 { associatedtype A associatedtype C } // CHECK-LABEL: sameTypeConcrete1@ // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.A == X3, τ_0_0.B == Int, τ_0_0.C == Int> func sameTypeConcrete1(_: T) where T.A == X3, T.C == T.B, T.C == Int { } // CHECK-LABEL: sameTypeConcrete2@ // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.B == X3, τ_0_0.C == X3> func sameTypeConcrete2(_: T) where T.B : X3, T.C == T.B, T.C == X3 { } // Note: a standard-library-based stress test to make sure we don't inject // any additional requirements. // CHECK-LABEL: RangeReplaceableCollection.f()@ // CHECK: <τ_0_0 where τ_0_0 : MutableCollection, τ_0_0 : RangeReplaceableCollection, τ_0_0.SubSequence == MutableRangeReplaceableSlice<τ_0_0>> extension RangeReplaceableCollection where Self: MutableCollection, Self.SubSequence == MutableRangeReplaceableSlice { func f() { } } // rdar://problem/30478915 protocol P11 { associatedtype A } protocol P12 { associatedtype B: P11 } struct X6 { } struct X7 : P11 { typealias A = X6 } struct X8 : P12 { typealias B = X7 } struct X9 where T.B == U.B { // CHECK-LABEL: X9.upperSameTypeConstraint // CHECK: Generic signature: // CHECK: Canonical generic signature: <τ_0_0, τ_0_1, τ_1_0 where τ_0_0 == X8, τ_0_1 : P12, τ_0_1.B == X7> func upperSameTypeConstraint(_: V) where T == X8 { } }