|
| 1 | +// RUN: %target-swift-emit-silgen -enable-subst-sil-function-types-for-function-values %s | %FileCheck %s |
| 2 | + |
| 3 | + |
| 4 | +// Similarly-abstract generic signatures should share an unsubstituted type |
| 5 | +// even in different generic contexts |
| 6 | + |
| 7 | +// CHECK-LABEL: sil {{.*}}1a{{.*}} : $@convention(thin) <T, U> (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <T, U>) -> () |
| 8 | +func a<T, U>(_ x: (T) -> U) {} |
| 9 | + |
| 10 | +// CHECK-LABEL: sil {{.*}}1b{{.*}} : $@convention(thin) <T, U> (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <U, T>) -> () |
| 11 | +func b<T, U>(_ x: (U) -> T) {} |
| 12 | + |
| 13 | +// CHECK-LABEL: sil {{.*}}1c{{.*}} : $@convention(thin) <T, U, V> (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <V, T>, @in_guaranteed U) -> () |
| 14 | +func c<T, U, V>(_ x: (V) -> T, _: U) {} |
| 15 | + |
| 16 | +// CHECK-LABEL: sil {{.*}}003Hca{{.*}} : $@convention(thin) <T> (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <T, T>) -> () |
| 17 | +func ç<T>(_ x: (T) -> T) {} |
| 18 | + |
| 19 | + |
| 20 | +// ...including unconstrained associated types |
| 21 | + |
| 22 | +protocol P { |
| 23 | + associatedtype A |
| 24 | +} |
| 25 | + |
| 26 | +// CHECK-LABEL: sil {{.*}}1d{{.*}} : $@convention(thin) <T where T : P> (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <T, T.A>) -> () |
| 27 | +func d<T: P>(_ x: (T) -> T.A) {} |
| 28 | + |
| 29 | +// CHECK-LABEL: sil {{.*}}1e{{.*}} : $@convention(thin) <T where T : P> (@noescape @callee_guaranteed <τ_0_0, τ_0_1> in (@in_guaranteed τ_0_0) -> @out τ_0_1 for <T.A, T>) -> () |
| 30 | +func e<T: P>(_ x: (T.A) -> T) {} |
| 31 | + |
| 32 | + |
| 33 | +// Preserve class constraints, because they're less abstract for layout and |
| 34 | +// calling convention purposes than unconstrained types |
| 35 | + |
| 36 | +// CHECK-LABEL: sil {{.*}}1f{{.*}} : $@convention(thin) <T, U where T : AnyObject> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : AnyObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for <T, U>) -> () |
| 37 | +func f<T: AnyObject, U>(_ x: (T) -> U) {} |
| 38 | + |
| 39 | +// CHECK-LABEL: sil {{.*}}1g{{.*}} : $@convention(thin) <T, U where T : AnyObject> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_1 : AnyObject> in (@in_guaranteed τ_0_0) -> @owned τ_0_1 for <U, T>) -> () |
| 40 | +func g<T: AnyObject, U>(_ x: (U) -> T) {} |
| 41 | + |
| 42 | +// CHECK-LABEL: sil {{.*}}1h{{.*}} : $@convention(thin) <T, U where T : AnyObject, U : AnyObject> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : AnyObject, τ_0_1 : AnyObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for <T, U>) -> () |
| 43 | +func h<T: AnyObject, U: AnyObject>(_ x: (T) -> U) {} |
| 44 | + |
| 45 | +// CHECK-LABEL: sil {{.*}}1i{{.*}} : $@convention(thin) <T, U where T : AnyObject, U : AnyObject> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : AnyObject, τ_0_1 : AnyObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for <U, T>) -> () |
| 46 | +func i<T: AnyObject, U: AnyObject>(_ x: (U) -> T) {} |
| 47 | + |
| 48 | + |
| 49 | +// Indirect class constraints |
| 50 | + |
| 51 | +protocol PC: AnyObject { } |
| 52 | + |
| 53 | +// CHECK-LABEL: sil {{.*}}1j{{.*}} : $@convention(thin) <T, U where T : PC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : AnyObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for <T, U>) -> () |
| 54 | +func j<T: PC, U>(_ x: (T) -> U) {} |
| 55 | + |
| 56 | +// CHECK-LABEL: sil {{.*}}1k{{.*}} : $@convention(thin) <T, U where T : PC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_1 : AnyObject> in (@in_guaranteed τ_0_0) -> @owned τ_0_1 for <U, T>) -> () |
| 57 | +func k<T: PC, U>(_ x: (U) -> T) {} |
| 58 | + |
| 59 | +// CHECK-LABEL: sil {{.*}}1l{{.*}} : $@convention(thin) <T, U where T : PC, U : PC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : AnyObject, τ_0_1 : AnyObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for <T, U>) -> () |
| 60 | +func l<T: PC, U: PC>(_ x: (T) -> U) {} |
| 61 | + |
| 62 | +// CHECK-LABEL: sil {{.*}}1m{{.*}} : $@convention(thin) <T, U where T : PC, U : PC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : AnyObject, τ_0_1 : AnyObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for <U, T>) -> () |
| 63 | +func m<T: PC, U: PC>(_ x: (U) -> T) {} |
| 64 | + |
| 65 | +// CHECK-LABEL: sil {{.*}}1n{{.*}} : $@convention(thin) <T where T : P, T : PC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : AnyObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for <T, T.A>) -> () |
| 66 | +func n<T: P & PC>(_ x: (T) -> T.A) {} |
| 67 | + |
| 68 | + |
| 69 | +// Superclass constraints |
| 70 | + |
| 71 | +class Base {} |
| 72 | + |
| 73 | +func o<T: Base, U> (_ x: (T) -> U) {} |
| 74 | + |
| 75 | + |
| 76 | +// Indirect constraints by associated type or protocol |
| 77 | + |
| 78 | +protocol PCAO: AnyObject { |
| 79 | + associatedtype A |
| 80 | +} |
| 81 | + |
| 82 | +protocol POAC { |
| 83 | + associatedtype A: AnyObject |
| 84 | +} |
| 85 | + |
| 86 | +protocol PCAC: AnyObject { |
| 87 | + associatedtype A: AnyObject |
| 88 | +} |
| 89 | + |
| 90 | +// CHECK-LABEL: sil {{.*}}1p{{.*}} : $@convention(thin) <T where T : PCAO> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : AnyObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for <T, T.A>) -> () |
| 91 | +func p<T: PCAO> (_ x: (T) -> T.A) {} |
| 92 | +// CHECK-LABEL: sil {{.*}}1q{{.*}} : $@convention(thin) <T where T : POAC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_1 : AnyObject> in (@in_guaranteed τ_0_0) -> @owned τ_0_1 for <T, T.A>) -> () |
| 93 | +func q<T: POAC> (_ x: (T) -> T.A) {} |
| 94 | +// CHECK-LABEL: sil {{.*}}1r{{.*}} : $@convention(thin) <T where T : PCAC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : AnyObject, τ_0_1 : AnyObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for <T, T.A>) -> () |
| 95 | +func r<T: PCAC> (_ x: (T) -> T.A) {} |
| 96 | + |
| 97 | + |
| 98 | +// Structural positions |
| 99 | + |
| 100 | +struct S<T, U> {} |
| 101 | + |
| 102 | +// CHECK-LABEL: sil {{.*}}1t{{.*}} : $@convention(thin) <T, U where U : AnyObject> (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : AnyObject, τ_0_3 : AnyObject> in (S<τ_0_0, τ_0_1>) -> (@out τ_0_2, @owned τ_0_3) for <T, U, T, U>) -> () |
| 103 | +func t<T, U: AnyObject>(_: (S<T, U>) -> (T, U)) {} |
| 104 | + |
| 105 | +// CHECK-LABEL: sil {{.*}}1u{{.*}} : $@convention(thin) <T> (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (S<τ_0_0, τ_0_1>) -> @out τ_0_2 for <T, T, T>) -> () |
| 106 | +func u<T>(_: (S<T, T>) -> T) {} |
| 107 | + |
| 108 | + |
| 109 | +class C<T, U> {} |
| 110 | + |
| 111 | +// CHECK-LABEL: sil {{.*}}1v{{.*}} : $@convention(thin) <T, U where U : AnyObject> (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_1 : AnyObject, τ_0_3 : AnyObject> in (@guaranteed C<τ_0_0, τ_0_1>) -> (@out τ_0_2, @owned τ_0_3) for <T, U, T, U>) -> () |
| 112 | +func v<T, U: AnyObject>(_: (C<T, U>) -> (T, U)) {} |
| 113 | + |
| 114 | +// CHECK-LABEL: sil {{.*}}1w{{.*}} : $@convention(thin) <T> (@noescape @callee_guaranteed <τ_0_0, τ_0_1, τ_0_2> in (@guaranteed C<τ_0_0, τ_0_1>) -> @out τ_0_2 for <T, T, T>) -> () |
| 115 | +func w<T>(_: (C<T, T>) -> T) {} |
| 116 | + |
| 117 | +// CHECK-LABEL: sil {{.*}}1x{{.*}} : $@convention(thin) <T, U, V where V : C<T, U>> (@noescape @callee_guaranteed <τ_0_0 where τ_0_0 : AnyObject> in (@guaranteed τ_0_0) -> () for <V>) -> () |
| 118 | +func x<T, U, V: C<T, U>>(_: (V) -> Void) {} |
0 commit comments