// RUN: %target-swift-emit-silgen %s | %FileCheck %s protocol P { associatedtype Assoc } protocol Q { associatedtype Assoc1 associatedtype Assoc2 } struct G {} class C {} func a(x: T) {} func b(x: G, y: T.Assoc) {} func c(x: T, y: T.Assoc) where T: P {} func d(x: T, y: U) {} func e(x: T, y: U) where T: P, U: P, U: Q {} // FIXME: Same-type constraints expose a typechecker bug. // func f(x: T) where T.Assoc1 == T.Assoc2 {} func g(x: T) where T: Q, T.Assoc1 == T.Assoc2 {} func h(x: T) where T.Assoc == U {} func i(x: T) where T.Assoc: Q, T.Assoc.Assoc1 == T.Assoc.Assoc2 {} func j(_: T) {} func k(_: T) where T: C {} func l(_: T) where T: P {} func m(_: T) where T.Assoc: C {} struct Foo { func z() {} func a(x: T) {} func b(x: G, y: T.Assoc) {} func c(x: T, y: T.Assoc) where T: P {} func d(x: T, y: U) {} func e(x: T, y: U) where T: P, U: P, U: Q {} func f(x: T) where T.Assoc1 == T.Assoc2 {} func g(x: T) where T: Q, T.Assoc1 == T.Assoc2 {} func h(x: T) where T.Assoc == U {} func i(x: T) where T.Assoc: Q, T.Assoc.Assoc1 == T.Assoc.Assoc2 {} func j(_: T) {} func k(_: T) where T: C {} func l(_: T) where T: P {} func m(_: T) where T.Assoc: C {} } // Test that we handle interface type lowering when accessing a dependent // member of a dependent member that substitutes to a type parameter. // protocol Fooable { associatedtype Foo } protocol Barrable { associatedtype Bar: Fooable func bar(_: Bar) -> Bar.Foo } struct FooBar: Barrable { typealias Bar = T func bar(_ x: T) -> T.Foo { } } // Test that associated types can be constrained to concrete types func concreteJungle(_: T) -> T.Foo where T : Fooable, T.Foo == C { return C() } func concreteJungle(_: T, t: T.Foo) -> C where T : Fooable, T.Foo == C { let c: C = t return c } func concreteJungle(_: T, f: @escaping (T.Foo) -> C) -> T.Foo where T : Fooable, T.Foo == C { let ff: (C) -> T.Foo = f return ff(C()) } protocol Whereable { associatedtype Assoc associatedtype Bssoc: Whereable } extension Whereable { // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures9WhereablePAAE19staticExtensionFunc3arg7ElementSTQz8IteratorSTQz_tSTRzrlFZ : $@convention(method) (@in_guaranteed Self.Iterator, @thick Self.Type) -> @out Self.Element static func staticExtensionFunc(arg: Self.Iterator) -> Self.Element where Self: Sequence { fatalError() } // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures9WhereablePAAE13extensionFuncyy5BssocQz5AssocRtzrlF : $@convention(method) (@in_guaranteed Self) -> () func extensionFunc() where Assoc == Bssoc { } // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures9WhereablePAAE5AssocQzycAabERQAD_5BssocQZAFRtzrluig : $@convention(method) (@in_guaranteed Self) -> @out Self.Assoc subscript() -> Assoc where Assoc: Whereable, Bssoc == Assoc.Bssoc { fatalError() } // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures9WhereablePAAE5AssocQzycAabERQ5Bssoc_ADQZAERSrluig : $@convention(method) (@in_guaranteed Self) -> @out Self.Assoc subscript() -> Assoc where Assoc: Whereable, Assoc == Bssoc.Assoc { fatalError() } } struct W1 {} struct W2 {} class Class { // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC9classFuncyyAA9WhereableRz5AssocQzRszlFZ : $@convention(method) (@thick Class.Type) -> () class func classFunc() where T: Whereable, T.Assoc == T { } // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC5func1yyAA7FooableRzlF : $@convention(method) (@guaranteed Class) -> () func func1() where T: Fooable { } // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC5func2yyAA2W1VRszlF : $@convention(method) (@guaranteed Class) -> () func func2() where T == W1 { } // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC5func2yyAA2W2VRszlF : $@convention(method) (@guaranteed Class) -> () func func2() where T == W2 { } // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC5AssocQzycAA9WhereableRzluig : $@convention(method) (@guaranteed Class) -> @out T.Assoc subscript() -> T.Assoc where T: Whereable { fatalError() } // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC06NestedC0CAEyx_Gycfc : $@convention(method) (@owned Class.NestedClass) -> @owned Class.NestedClass class NestedClass where T: Fooable { } } extension Class where T: Whereable { // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassCA2A9WhereableRzlE13extensionFuncyyAA7FooableRzrlF : $@convention(method) (@guaranteed Class) -> () func extensionFunc() where T: Fooable { } } extension Class.NestedClass { // CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC06NestedC0C3foo3argyx_tAA9WhereableRz3FooAA7FooablePQz5AssocAaHPRtzrlF : $@convention(method) (@in_guaranteed T, @guaranteed Class.NestedClass) -> () func foo(arg: T) where T: Whereable, T.Foo == T.Assoc { } }