// RUN: %target-typecheck-verify-swift -typecheck -verify // RUN: %target-typecheck-verify-swift -typecheck -debug-generic-signatures > %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 { _ = 0 x.p1() } // Infer protocol requirements from the superclass of a generic parameter. func inferFromSuperclass>(_ t: T, u: U) -> T { _ = 0 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 { func unpack(_ x: X1) {} func unpackFail(_ X: X1) { } // expected-error{{type 'U' does not conform to protocol 'P1'}} } // ---------------------------------------------------------------------------- // Superclass requirements // ---------------------------------------------------------------------------- // Compute meet of two superclass requirements correctly. class Carnivora {} class Canidae : Carnivora {} struct U {} struct V {} // CHECK-LABEL: .inferSuperclassRequirement1@ // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : Canidae> func inferSuperclassRequirement1( _ v: V) {} // CHECK-LABEL: .inferSuperclassRequirement2@ // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : Canidae> func inferSuperclassRequirement2(_ v: U) {} // ---------------------------------------------------------------------------- // Same-type requirements // ---------------------------------------------------------------------------- protocol P3 { associatedtype P3Assoc : P2 // expected-note{{declared here}} } 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 {} func inferSameType1(_ x: Model_P3_P4_Eq) { let u: U.P4Assoc? = nil let _: T.P3Assoc? = u! } func inferSameType2(_: T, _: U) where U.P4Assoc : P2, T.P3Assoc == U.P4Assoc {} // expected-warning@-1{{redundant conformance constraint 'T.P3Assoc': 'P2'}} // expected-note@-2{{conformance constraint 'T.P3Assoc': 'P2' implied here}} 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@ // 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, // expected-note{{conformance constraint 'Self.AssocP6.Element': 'P6' written here}} AssocP7.AssocP6.Element : P6, // expected-warning{{redundant conformance constraint 'Self.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 { } // expected-warning@-1{{redundant superclass constraint 'T.B' : 'X3'}} // expected-note@-2{{same-type constraint 'T.C' == 'X3' written here}} // Note: a standard-library-based stress test to make sure we don't inject // any additional requirements. // CHECK-LABEL: RangeReplaceableCollection // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : MutableCollection, τ_0_0 : RangeReplaceableCollection, τ_0_0.SubSequence == Slice<τ_0_0>> extension RangeReplaceableCollection where Self: MutableCollection, Self.SubSequence == Slice { func f() { } } // CHECK-LABEL: X14.recursiveConcreteSameType // CHECK: Generic signature: > // CHECK-NEXT: Canonical generic signature: <τ_0_0, τ_1_0 where τ_0_0 == Range> struct X14 where T.Iterator == IndexingIterator { func recursiveConcreteSameType(_: V) where T == Range { } } // 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 { } } protocol P13 { associatedtype C: P11 } struct X10: P11, P12 { typealias A = X10 typealias B = X10 } struct X11 where T.B == U.B.A { // CHECK-LABEL: X11.upperSameTypeConstraint // CHECK: Generic signature: // CHECK: Canonical generic signature: <τ_0_0, τ_0_1, τ_1_0 where τ_0_0 : P12, τ_0_1 == X10, τ_0_0.B == X10> func upperSameTypeConstraint(_: V) where U == X10 { } } #if _runtime(_ObjC) // rdar://problem/30610428 @objc protocol P14 { } class X12 { func bar(v: V) where S == P14 { } } @objc protocol P15: P14 { } class X13 { func bar(v: V) where S == P15 { } } #endif protocol P16 { associatedtype A } struct X15 { } struct X16 : P16 { typealias A = (X, Y) } // CHECK-LABEL: .X17.bar@ // CHECK: Generic signature: , T == X3, U == X15> struct X17 where S.A == (T, U) { func bar(_: V) where S == X16 { } } // Same-type constraints that are self-derived via a parent need to be // suppressed in the resulting signature. protocol P17 { } protocol P18 { associatedtype A: P17 } struct X18: P18, P17 { typealias A = X18 } // CHECK-LABEL: .X19.foo@ // CHECK: Generic signature: struct X19 where T == T.A { func foo(_: U) where T == X18 { } } // rdar://problem/31520386 protocol P20 { } struct X20 { } // CHECK-LABEL: .X21.f@ // CHECK: Generic signature: > // CHECK: Canonical generic signature: <τ_0_0, τ_0_1, τ_1_0 where τ_0_0 : P20, τ_0_1 == X20<τ_0_0>> struct X21 { func f(_: V) where U == X20 { } } struct X22 { func g(_: V) where T: P20, U == X20 { } } // CHECK: Generic signature: // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P22> // CHECK: Protocol requirement signature: // CHECK: .P22@ // CHECK-NEXT: Requirement signature: , Self.B : P20> // CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X20<τ_0_0.B>, τ_0_0.B : P20> protocol P22 { associatedtype A associatedtype B: P20 where A == X20 } // CHECK: Generic signature: // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P23> // CHECK: Protocol requirement signature: // CHECK: .P23@ // CHECK-NEXT: Requirement signature: , Self.B : P20> // CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X20<τ_0_0.B>, τ_0_0.B : P20> protocol P23 { associatedtype A associatedtype B: P20 where A == X20 } protocol P24 { associatedtype C: P20 } struct X24 : P24 { typealias C = T } // CHECK-LABEL: .P25a@ // CHECK-NEXT: Requirement signature: , Self.B : P20> // CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X24<τ_0_0.B>, τ_0_0.B : P20> protocol P25a { associatedtype A: P24 // expected-warning{{redundant conformance constraint 'Self.A': 'P24'}} associatedtype B: P20 where A == X24 // expected-note{{conformance constraint 'Self.A': 'P24' implied here}} } // CHECK-LABEL: .P25b@ // CHECK-NEXT: Requirement signature: , Self.B : P20> // CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X24<τ_0_0.B>, τ_0_0.B : P20> protocol P25b { associatedtype A associatedtype B: P20 where A == X24 } protocol P25c { associatedtype A: P24 associatedtype B where A == X // expected-error{{use of undeclared type 'X'}} } protocol P25d { associatedtype A associatedtype B where A == X24 // expected-error{{type 'Self.B' does not conform to protocol 'P20'}} } // Similar to the above, but with superclass constraints. protocol P26 { associatedtype C: X3 } struct X26 : P26 { typealias C = T } // CHECK-LABEL: .P27a@ // CHECK-NEXT: Requirement signature: , Self.B : X3> // CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X26<τ_0_0.B>, τ_0_0.B : X3> protocol P27a { associatedtype A: P26 // expected-warning{{redundant conformance constraint 'Self.A': 'P26'}} associatedtype B: X3 where A == X26 // expected-note{{conformance constraint 'Self.A': 'P26' implied here}} } // CHECK-LABEL: .P27b@ // CHECK-NEXT: Requirement signature: , Self.B : X3> // CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X26<τ_0_0.B>, τ_0_0.B : X3> protocol P27b { associatedtype A associatedtype B: X3 where A == X26 } // ---------------------------------------------------------------------------- // Inference of associated type relationships within a protocol hierarchy // ---------------------------------------------------------------------------- struct X28 : P2 { func p1() { } } // CHECK-LABEL: .P28@ // CHECK-NEXT: Requirement signature: // CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : P3, τ_0_0.P3Assoc == X28> protocol P28: P3 { typealias P3Assoc = X28 // expected-warning{{typealias overriding associated type}} } // ---------------------------------------------------------------------------- // Inference of associated types by name match // ---------------------------------------------------------------------------- protocol P29 { associatedtype X } protocol P30 { associatedtype X } protocol P31 { } // CHECK-LABEL: .sameTypeNameMatch1@ // CHECK: Generic signature: func sameTypeNameMatch1(_: T) where T.X: P31 { } // ---------------------------------------------------------------------------- // Infer requirements from conditional conformances // ---------------------------------------------------------------------------- protocol P32 {} protocol P33 { associatedtype A: P32 } protocol P34 {} struct Foo {} extension Foo: P32 where T: P34 {} // Inference chain: U.A: P32 => Foo: P32 => V: P34 // CHECK-LABEL: conditionalConformance1@ // CHECK: Generic signature: > // CHECK: Canonical generic signature: <τ_0_0, τ_0_1 where τ_0_0 : P33, τ_0_1 : P34, τ_0_0.A == Foo<τ_0_1>> func conditionalConformance1(_: U) where U.A == Foo {} struct Bar {} // CHECK-LABEL: conditionalConformance2@ // CHECK: Generic signature: // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P34> func conditionalConformance2(_: Bar>) {} // Mentioning a nested type that is conditional should infer that requirement (SR 6850) protocol P35 {} protocol P36 { func foo() } struct ConditionalNested {} extension ConditionalNested where T: P35 { struct Inner {} } // CHECK: Generic signature: // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P35, τ_0_0 : P36> extension ConditionalNested.Inner: P36 where T: P36 { func foo() {} struct Inner2 {} } // CHECK-LABEL: conditionalNested1@ // CHECK: Generic signature: // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P35> func conditionalNested1(_: [ConditionalNested.Inner?]) {} // CHECK-LABEL: conditionalNested2@ // CHECK: Generic signature: // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P35, τ_0_0 : P36> func conditionalNested2(_: [ConditionalNested.Inner.Inner2?]) {} // // Generate typalias adds requirements that can be inferred // typealias X1WithP2 = X1 // Inferred requirement T: P2 from the typealias func testX1WithP2(_: X1WithP2) { _ = X5() // requires P2 } // Overload based on the inferred requirement. func testX1WithP2Overloading(_: X1) { _ = X5() // expected-error{{type 'T' does not conform to protocol 'P2'}} } func testX1WithP2Overloading(_: X1WithP2) { _ = X5() // requires P2 } // Extend using the inferred requirement. extension X1WithP2 { func f() { _ = X5() // okay: inferred T: P2 from generic typealias } } extension X1: P1 { func p1() { } } typealias X1WithP2Changed = X1> typealias X1WithP2MoreArgs = X1 extension X1WithP2Changed { func bad1() { _ = X5() // expected-error{{type 'T' does not conform to protocol 'P2'}} } } extension X1WithP2MoreArgs { func bad2() { _ = X5() // expected-error{{type 'T' does not conform to protocol 'P2'}} } } // Inference from protocol inheritance clauses. typealias ExistentialP4WithP2Assoc = P4 where T.P4Assoc : P2 protocol P37 : ExistentialP4WithP2Assoc { } extension P37 { func f() { _ = X5() // requires P2 } }