You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SIL: Type lowering for function values with substituted SIL function types.
After converting a function type to its corresponding SIL type by our usual rules, extract
the substituted generic signature and common interface type for all concrete function types
that the function could be called as. We don't currently have any use cases for distinguishing
types at finer granularity than generic class-constrained/generic unconstrained/not-generic, so
to reduce the amount of conversion noise in SIL, generate the most general generic signature
possible, by extracting every position with a dependent generic parameter or associated type thereof
into a separate generic parameter in the substituted signature, discarding all constraints except
for `AnyObject` layout constraints. This way, if `foo<T>(x: (T, T) -> ())` calls
`bar<T, U>(x: (T, U) -> ())` and forwards `x` along, the two closures that only vary in genericity
don't need a conversion even with substituted function types, because they'll both have the same
abstract lowering `<A, B> (A, B) -> ()` with different substitutions.
// 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
+
protocolP{
23
+
associatedtypeA
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 : _RefCountedObject> 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 : _RefCountedObject> 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 : _RefCountedObject, τ_0_1 : _RefCountedObject> 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 : _RefCountedObject, τ_0_1 : _RefCountedObject> 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
+
protocolPC:AnyObject{}
52
+
53
+
// CHECK-LABEL: sil {{.*}}1j{{.*}} : $@convention(thin) <T, U where T : PC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> 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 : _RefCountedObject> 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 : _RefCountedObject, τ_0_1 : _RefCountedObject> 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 : _RefCountedObject, τ_0_1 : _RefCountedObject> 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 : _RefCountedObject> 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
+
classBase{}
72
+
73
+
// CHECK-LABEL: sil {{.*}}1o{{.*}} : $@convention(thin) <T, U where T : Base> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for <T, U>) -> ()
74
+
func o<T:Base, U>(_ x:(T)->U){}
75
+
76
+
77
+
// Indirect constraints by associated type or protocol
78
+
79
+
protocolPCAO:AnyObject{
80
+
associatedtypeA
81
+
}
82
+
83
+
protocolPOAC{
84
+
associatedtypeA:AnyObject
85
+
}
86
+
87
+
protocolPCAC:AnyObject{
88
+
associatedtypeA:AnyObject
89
+
}
90
+
91
+
// CHECK-LABEL: sil {{.*}}1p{{.*}} : $@convention(thin) <T where T : PCAO> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> @out τ_0_1 for <T, T.A>) -> ()
92
+
func p<T:PCAO>(_ x:(T)->T.A){}
93
+
// CHECK-LABEL: sil {{.*}}1q{{.*}} : $@convention(thin) <T where T : POAC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_1 : _RefCountedObject> in (@in_guaranteed τ_0_0) -> @owned τ_0_1 for <T, T.A>) -> ()
94
+
func q<T:POAC>(_ x:(T)->T.A){}
95
+
// CHECK-LABEL: sil {{.*}}1r{{.*}} : $@convention(thin) <T where T : PCAC> (@noescape @callee_guaranteed <τ_0_0, τ_0_1 where τ_0_0 : _RefCountedObject, τ_0_1 : _RefCountedObject> in (@guaranteed τ_0_0) -> @owned τ_0_1 for <T, T.A>) -> ()
96
+
func r<T:PCAC>(_ x:(T)->T.A){}
97
+
98
+
99
+
// Structural positions
100
+
101
+
structS<T, U>{}
102
+
103
+
// 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 : _RefCountedObject, τ_0_3 : _RefCountedObject> in (S<τ_0_0, τ_0_1>) -> (@out τ_0_2, @owned τ_0_3) for <T, U, T, U>) -> ()
104
+
func t<T, U:AnyObject>(_:(S<T,U>)->(T,U)){}
105
+
106
+
// 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>) -> ()
107
+
func u<T>(_:(S<T,T>)->T){}
108
+
109
+
110
+
classC<T, U>{}
111
+
112
+
// 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 : _RefCountedObject, τ_0_3 : _RefCountedObject> in (@guaranteed C<τ_0_0, τ_0_1>) -> (@out τ_0_2, @owned τ_0_3) for <T, U, T, U>) -> ()
113
+
func v<T, U:AnyObject>(_:(C<T,U>)->(T,U)){}
114
+
115
+
// 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>) -> ()
116
+
func w<T>(_:(C<T,T>)->T){}
117
+
118
+
// CHECK-LABEL: sil {{.*}}1x{{.*}} : $@convention(thin) <T, U, V where V : C<T, U>> (@noescape @callee_guaranteed <τ_0_0 where τ_0_0 : _RefCountedObject> in (@guaranteed τ_0_0) -> () for <V>) -> ()
119
+
func x<T, U, V:C<T,U>>(_:(V)->Void){}
120
+
121
+
122
+
// Opaque types should not be extracted as substituted arguments because they
0 commit comments