1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
protocol P {
associatedtype Assoc
}
protocol Q {
associatedtype Assoc1
associatedtype Assoc2
}
struct G<T> {}
class C {}
func a<T>(x: T) {}
func b<T: P>(x: G<T>, y: T.Assoc) {}
func c<T>(x: T, y: T.Assoc) where T: P {}
func d<T: P, U: P & Q>(x: T, y: U) {}
func e<T, U>(x: T, y: U) where T: P, U: P, U: Q {}
// FIXME: Same-type constraints expose a typechecker bug.
// <rdar://problem/15730168>
func f<T: Q>(x: T) where T.Assoc1 == T.Assoc2 {}
func g<T>(x: T) where T: Q, T.Assoc1 == T.Assoc2 {}
func h<T: P, U>(x: T) where T.Assoc == U {}
func i<T: P>(x: T) where T.Assoc: Q, T.Assoc.Assoc1 == T.Assoc.Assoc2 {}
func j<T: C>(_: T) {}
func k<T>(_: T) where T: C {}
func l<T: C>(_: T) where T: P {}
func m<T: P>(_: T) where T.Assoc: C {}
struct Foo<V> {
func z() {}
func a<T>(x: T) {}
func b<T: P>(x: G<T>, y: T.Assoc) {}
func c<T>(x: T, y: T.Assoc) where T: P {}
func d<T: P, U: P & Q>(x: T, y: U) {}
func e<T, U>(x: T, y: U) where T: P, U: P, U: Q {}
func f<T: Q>(x: T) where T.Assoc1 == T.Assoc2 {}
func g<T>(x: T) where T: Q, T.Assoc1 == T.Assoc2 {}
func h<T: P, U>(x: T) where T.Assoc == U {}
func i<T: P>(x: T) where T.Assoc: Q, T.Assoc.Assoc1 == T.Assoc.Assoc2 {}
func j<T: C>(_: T) {}
func k<T>(_: T) where T: C {}
func l<T: C>(_: T) where T: P {}
func m<T: P>(_: 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.
// <rdar://problem/16257259>
protocol Fooable {
associatedtype Foo
}
protocol Barrable {
associatedtype Bar: Fooable
func bar(_: Bar) -> Bar.Foo
}
struct FooBar<T: Fooable>: Barrable {
typealias Bar = T
func bar(_ x: T) -> T.Foo { }
}
// Test that associated types can be constrained to concrete types
func concreteJungle<T>(_: T) -> T.Foo where T : Fooable, T.Foo == C {
return C()
}
func concreteJungle<T>(_: T, t: T.Foo) -> C where T : Fooable, T.Foo == C {
let c: C = t
return c
}
func concreteJungle<T>(_: 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) <Self where Self : Sequence, Self : Whereable> (@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) <Self where Self : Whereable, Self.Assoc == Self.Bssoc> (@in_guaranteed Self) -> ()
func extensionFunc() where Assoc == Bssoc { }
// CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures9WhereablePAAE5AssocQzycAabERQAD_5BssocQZAFRtzrluig : $@convention(method) <Self where Self : Whereable, Self.Assoc : Whereable, Self.Bssoc == Self.Assoc.Bssoc> (@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) <Self where Self : Whereable, Self.Assoc : Whereable, Self.Assoc == Self.Bssoc.Assoc> (@in_guaranteed Self) -> @out Self.Assoc
subscript() -> Assoc
where Assoc: Whereable, Assoc == Bssoc.Assoc {
fatalError()
}
}
struct W1 {}
struct W2 {}
class Class<T> {
// CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC9classFuncyyAA9WhereableRz5AssocQzRszlFZ : $@convention(method) <T where T : Whereable, T == T.Assoc> (@thick Class<T>.Type) -> ()
class func classFunc() where T: Whereable, T.Assoc == T { }
// CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC5func1yyAA7FooableRzlF : $@convention(method) <T where T : Fooable> (@guaranteed Class<T>) -> ()
func func1() where T: Fooable { }
// CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC5func2yyAA2W1VRszlF : $@convention(method) (@guaranteed Class<W1>) -> ()
func func2() where T == W1 { }
// CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC5func2yyAA2W2VRszlF : $@convention(method) (@guaranteed Class<W2>) -> ()
func func2() where T == W2 { }
// CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC5AssocQzycAA9WhereableRzluig : $@convention(method) <T where T : Whereable> (@guaranteed Class<T>) -> @out T.Assoc
subscript() -> T.Assoc where T: Whereable {
fatalError()
}
// CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC06NestedC0CAEyx_Gycfc : $@convention(method) <T where T : Fooable> (@owned Class<T>.NestedClass) -> @owned Class<T>.NestedClass
class NestedClass where T: Fooable { }
}
extension Class where T: Whereable {
// CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassCA2A9WhereableRzlE13extensionFuncyyAA7FooableRzrlF : $@convention(method) <T where T : Fooable, T : Whereable> (@guaranteed Class<T>) -> ()
func extensionFunc() where T: Fooable { }
}
extension Class.NestedClass {
// CHECK-LABEL: sil hidden [ossa] @$s18generic_signatures5ClassC06NestedC0C3foo3argyx_tAA9WhereableRz3FooAA7FooablePQz5AssocAaHPRtzrlF : $@convention(method) <T where T : Fooable, T : Whereable, T.Assoc == T.Foo> (@in_guaranteed T, @guaranteed Class<T>.NestedClass) -> ()
func foo(arg: T) where T: Whereable, T.Foo == T.Assoc { }
}
|