Skip to content

Commit 87b2ddb

Browse files
committed
SILGen: Add tests for protocols with superclass contraints
1 parent cb4a248 commit 87b2ddb

File tree

1 file changed

+251
-0
lines changed

1 file changed

+251
-0
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
// RUN: %target-swift-emit-silgen -enable-sil-ownership %s | tee /tmp/xxx | %FileCheck %s
2+
3+
// Protocols with superclass-constrained Self.
4+
5+
class Concrete {
6+
typealias ConcreteAlias = String
7+
8+
func concreteMethod(_: ConcreteAlias) {}
9+
}
10+
11+
class Generic<T> : Concrete {
12+
typealias GenericAlias = (T, T)
13+
14+
func genericMethod(_: GenericAlias) {}
15+
}
16+
17+
protocol BaseProto {}
18+
19+
protocol ProtoRefinesClass : Generic<Int>, BaseProto {
20+
func requirementUsesClassTypes(_: ConcreteAlias, _: GenericAlias)
21+
}
22+
23+
extension ProtoRefinesClass {
24+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass17ProtoRefinesClassPAAE019extensionMethodUsesF5TypesyySS_Si_SittF : $@convention(method) <Self where Self : ProtoRefinesClass> (@guaranteed String, Int, Int, @guaranteed Self) -> ()
25+
func extensionMethodUsesClassTypes(_ x: ConcreteAlias, _ y: GenericAlias) {
26+
_ = ConcreteAlias.self
27+
_ = GenericAlias.self
28+
29+
// CHECK: [[SELF:%.*]] = copy_value %3 : $Self
30+
// CHECK-NEXT: [[UPCAST:%.*]] = upcast [[SELF]] : $Self to $Generic<Int>
31+
// CHECK-NEXT: [[UPCAST2:%.*]] = upcast [[UPCAST]] : $Generic<Int> to $Concrete
32+
// CHECK-NEXT: [[BORROW:%.*]] = begin_borrow [[UPCAST2]] : $Concrete
33+
// CHECK-NEXT: [[METHOD:%.*]] = class_method [[BORROW:%.*]] : $Concrete, #Concrete.concreteMethod!1 : (Concrete) -> (String) -> (), $@convention(method) (@guaranteed String, @guaranteed Concrete) -> ()
34+
// CHECK-NEXT: apply [[METHOD]](%0, [[BORROW]])
35+
// CHECK-NEXT: end_borrow [[BORROW]]
36+
// CHECK-NEXT: destroy_value [[UPCAST2]]
37+
concreteMethod(x)
38+
39+
// CHECK: [[SELF:%.*]] = copy_value %3 : $Self
40+
// CHECK-NEXT: [[UPCAST:%.*]] = upcast [[SELF]] : $Self to $Generic<Int>
41+
// CHECK-NEXT: [[BORROW:%.*]] = begin_borrow [[UPCAST]] : $Generic<Int>
42+
// CHECK: [[METHOD:%.*]] = class_method [[BORROW:%.*]] : $Generic<Int>, #Generic.genericMethod!1 : <T> (Generic<T>) -> ((T, T)) -> (), $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, @guaranteed Generic<τ_0_0>) -> ()
43+
// CHECK-NEXT: apply [[METHOD]]<Int>({{.*}}, [[BORROW]])
44+
// CHECK: end_borrow [[BORROW]]
45+
// CHECK-NEXT: destroy_value [[UPCAST]]
46+
genericMethod(y)
47+
48+
// CHECK: [[SELF:%.*]] = copy_value %3 : $Self
49+
// CHECK-NEXT: [[UPCAST:%.*]] = upcast [[SELF]] : $Self to $Generic<Int>
50+
// CHECK-NEXT: destroy_value [[UPCAST]] : $Generic<Int>
51+
let _: Generic<Int> = self
52+
53+
// CHECK: [[SELF:%.*]] = copy_value %3 : $Self
54+
// CHECK-NEXT: [[UPCAST:%.*]] = upcast [[SELF]] : $Self to $Generic<Int>
55+
// CHECK-NEXT: [[UPCAST2:%.*]] = upcast [[UPCAST]] : $Generic<Int> to $Concrete
56+
// CHECK-NEXT: destroy_value [[UPCAST2]] : $Concrete
57+
let _: Concrete = self
58+
59+
// CHECK: [[BOX:%.*]] = alloc_stack $BaseProto
60+
// CHECK-NEXT: [[ADDR:%.*]] = init_existential_addr [[BOX]] : $*BaseProto, $Self
61+
// CHECK-NEXT: [[SELF:%.*]] = copy_value %3 : $Self
62+
// CHECK-NEXT: store [[SELF]] to [init] [[ADDR]] : $*Self
63+
// CHECK-NEXT: destroy_addr [[BOX]] : $*BaseProto
64+
// CHECK-NEXT: dealloc_stack [[BOX]] : $*BaseProto
65+
let _: BaseProto = self
66+
67+
// CHECK: [[SELF:%.*]] = copy_value %3 : $Self
68+
// CHECK-NEXT: [[EXISTENTIAL:%.*]] = init_existential_ref [[SELF]] : $Self : $Self, $Generic<Int> & BaseProto
69+
let _: BaseProto & Generic<Int> = self
70+
71+
// CHECK: [[SELF:%.*]] = copy_value %3 : $Self
72+
// CHECK-NEXT: [[EXISTENTIAL:%.*]] = init_existential_ref [[SELF]] : $Self : $Self, $Concrete & BaseProto
73+
let _: BaseProto & Concrete = self
74+
75+
// CHECK: return
76+
}
77+
}
78+
79+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass22usesProtoRefinesClass1yyAA0eF5Class_pF : $@convention(thin) (@guaranteed ProtoRefinesClass) -> ()
80+
func usesProtoRefinesClass1(_ t: ProtoRefinesClass) {
81+
let x: ProtoRefinesClass.ConcreteAlias = "hi"
82+
_ = ProtoRefinesClass.ConcreteAlias.self
83+
84+
t.concreteMethod(x)
85+
86+
let y: ProtoRefinesClass.GenericAlias = (1, 2)
87+
_ = ProtoRefinesClass.GenericAlias.self
88+
89+
t.genericMethod(y)
90+
91+
t.requirementUsesClassTypes(x, y)
92+
93+
let _: Generic<Int> = t
94+
let _: Concrete = t
95+
let _: BaseProto = t
96+
let _: BaseProto & Generic<Int> = t
97+
let _: BaseProto & Concrete = t
98+
}
99+
100+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass22usesProtoRefinesClass2yyxAA0eF5ClassRzlF : $@convention(thin) <T where T : ProtoRefinesClass> (@guaranteed T) -> ()
101+
func usesProtoRefinesClass2<T : ProtoRefinesClass>(_ t: T) {
102+
let x: T.ConcreteAlias = "hi"
103+
_ = T.ConcreteAlias.self
104+
105+
t.concreteMethod(x)
106+
107+
let y: T.GenericAlias = (1, 2)
108+
_ = T.GenericAlias.self
109+
110+
t.genericMethod(y)
111+
112+
t.requirementUsesClassTypes(x, y)
113+
114+
let _: Generic<Int> = t
115+
let _: Concrete = t
116+
let _: BaseProto = t
117+
let _: BaseProto & Generic<Int> = t
118+
let _: BaseProto & Concrete = t
119+
}
120+
121+
class GoodConformingClass : Generic<Int>, ProtoRefinesClass {
122+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass19GoodConformingClassC015requirementUsesF5TypesyySS_Si_SittF : $@convention(method) (@guaranteed String, Int, Int, @guaranteed GoodConformingClass) -> ()
123+
func requirementUsesClassTypes(_ x: ConcreteAlias, _ y: GenericAlias) {
124+
_ = ConcreteAlias.self
125+
_ = GenericAlias.self
126+
127+
concreteMethod(x)
128+
129+
genericMethod(y)
130+
}
131+
}
132+
133+
protocol ProtoRefinesProtoWithClass : ProtoRefinesClass {}
134+
135+
extension ProtoRefinesProtoWithClass {
136+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass012ProtoRefinesD9WithClassPAAE026anotherExtensionMethodUsesG5TypesyySS_Si_SittF : $@convention(method) <Self where Self : ProtoRefinesProtoWithClass> (@guaranteed String, Int, Int, @guaranteed Self) -> ()
137+
func anotherExtensionMethodUsesClassTypes(_ x: ConcreteAlias, _ y: GenericAlias) {
138+
_ = ConcreteAlias.self
139+
_ = GenericAlias.self
140+
141+
concreteMethod(x)
142+
genericMethod(y)
143+
144+
let _: Generic<Int> = self
145+
let _: Concrete = self
146+
let _: BaseProto = self
147+
let _: BaseProto & Generic<Int> = self
148+
let _: BaseProto & Concrete = self
149+
}
150+
}
151+
152+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass016usesProtoRefinesE10WithClass1yyAA0efeG5Class_pF : $@convention(thin) (@guaranteed ProtoRefinesProtoWithClass) -> ()
153+
func usesProtoRefinesProtoWithClass1(_ t: ProtoRefinesProtoWithClass) {
154+
let x: ProtoRefinesProtoWithClass.ConcreteAlias = "hi"
155+
_ = ProtoRefinesProtoWithClass.ConcreteAlias.self
156+
157+
t.concreteMethod(x)
158+
159+
let y: ProtoRefinesProtoWithClass.GenericAlias = (1, 2)
160+
_ = ProtoRefinesProtoWithClass.GenericAlias.self
161+
162+
t.genericMethod(y)
163+
164+
t.requirementUsesClassTypes(x, y)
165+
166+
let _: Generic<Int> = t
167+
let _: Concrete = t
168+
let _: BaseProto = t
169+
let _: BaseProto & Generic<Int> = t
170+
let _: BaseProto & Concrete = t
171+
}
172+
173+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass016usesProtoRefinesE10WithClass2yyxAA0efeG5ClassRzlF : $@convention(thin) <T where T : ProtoRefinesProtoWithClass> (@guaranteed T) -> ()
174+
func usesProtoRefinesProtoWithClass2<T : ProtoRefinesProtoWithClass>(_ t: T) {
175+
let x: T.ConcreteAlias = "hi"
176+
_ = T.ConcreteAlias.self
177+
178+
t.concreteMethod(x)
179+
180+
let y: T.GenericAlias = (1, 2)
181+
_ = T.GenericAlias.self
182+
183+
t.genericMethod(y)
184+
185+
t.requirementUsesClassTypes(x, y)
186+
187+
let _: Generic<Int> = t
188+
let _: Concrete = t
189+
let _: BaseProto = t
190+
let _: BaseProto & Generic<Int> = t
191+
let _: BaseProto & Concrete = t
192+
}
193+
194+
class ClassWithInits<T> {
195+
init(notRequiredInit: ()) {}
196+
197+
required init(requiredInit: ()) {}
198+
}
199+
200+
protocol ProtocolWithClassInits : ClassWithInits<Int> {}
201+
202+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass26useProtocolWithClassInits1yyAA0efG5Inits_pXpF : $@convention(thin) (@thick ProtocolWithClassInits.Type) -> ()
203+
func useProtocolWithClassInits1(_ t: ProtocolWithClassInits.Type) {
204+
// CHECK: [[OPENED:%.*]] = open_existential_metatype %0 : $@thick ProtocolWithClassInits.Type
205+
// CHECK-NEXT: [[UPCAST:%.*]] = upcast [[OPENED]] : $@thick (@opened("{{.*}}") ProtocolWithClassInits).Type to $@thick ClassWithInits<Int>.Type
206+
// CHECK-NEXT: [[METHOD:%.*]] = class_method [[UPCAST]] : $@thick ClassWithInits<Int>.Type, #ClassWithInits.init!allocator.1 : <T> (ClassWithInits<T>.Type) -> (()) -> ClassWithInits<T>, $@convention(method) <τ_0_0> (@thick ClassWithInits<τ_0_0>.Type) -> @owned ClassWithInits<τ_0_0>
207+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]<Int>([[UPCAST]])
208+
// CHECK-NEXT: [[CAST:%.*]] = unchecked_ref_cast [[RESULT]] : $ClassWithInits<Int> to $@opened("{{.*}}") ProtocolWithClassInits
209+
// CHECK-NEXT: [[EXISTENTIAL:%.*]] = init_existential_ref [[CAST]] : $@opened("{{.*}}") ProtocolWithClassInits : $@opened("{{.*}}") ProtocolWithClassInits, $ProtocolWithClassInits
210+
// CHECK-NEXT: destroy_value [[EXISTENTIAL]]
211+
let _: ProtocolWithClassInits = t.init(requiredInit: ())
212+
}
213+
214+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass26useProtocolWithClassInits2yyxmAA0efG5InitsRzlF : $@convention(thin) <T where T : ProtocolWithClassInits> (@thick T.Type) -> ()
215+
func useProtocolWithClassInits2<T : ProtocolWithClassInits>(_ t: T.Type) {
216+
let _: T = T(requiredInit: ())
217+
218+
let _: T = t.init(requiredInit: ())
219+
}
220+
221+
protocol ProtocolRefinesClassInits : ProtocolWithClassInits {}
222+
223+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass29useProtocolRefinesClassInits1yyAA0efG5Inits_pXpF : $@convention(thin) (@thick ProtocolRefinesClassInits.Type) -> ()
224+
func useProtocolRefinesClassInits1(_ t: ProtocolRefinesClassInits.Type) {
225+
let _: ProtocolRefinesClassInits = t.init(requiredInit: ())
226+
}
227+
228+
// CHECK-LABEL: sil hidden @$S24protocol_with_superclass29useProtocolRefinesClassInits2yyxmAA0efG5InitsRzlF : $@convention(thin) <T where T : ProtocolRefinesClassInits> (@thick T.Type) -> ()
229+
func useProtocolRefinesClassInits2<T : ProtocolRefinesClassInits>(_ t: T.Type) {
230+
let _: T = T(requiredInit: ())
231+
232+
let _: T = t.init(requiredInit: ())
233+
}
234+
235+
class ClassWithDefault<T> {
236+
func makeT() -> T { }
237+
}
238+
239+
protocol SillyDefault : ClassWithDefault<Int> {
240+
func makeT() -> Int
241+
}
242+
243+
class ConformsToSillyDefault : ClassWithDefault<Int>, SillyDefault {}
244+
245+
// CHECK-LABEL: sil private [transparent] [thunk] @$S24protocol_with_superclass22ConformsToSillyDefaultCAA0fG0A2aDP5makeTSiyFTW : $@convention(witness_method: SillyDefault) (@guaranteed ConformsToSillyDefault) -> Int
246+
// CHECK: class_method %1 : $ClassWithDefault<Int>, #ClassWithDefault.makeT!1 : <T> (ClassWithDefault<T>) -> () -> T, $@convention(method) <τ_0_0> (@guaranteed ClassWithDefault<τ_0_0>) -> @out τ_0_0
247+
// CHECK: return
248+
249+
// CHECK-LABEL: sil_witness_table hidden ConformsToSillyDefault: SillyDefault module protocol_with_superclass {
250+
// CHECK-NEXT: method #SillyDefault.makeT!1: <Self where Self : SillyDefault> (Self) -> () -> Int : @$S24protocol_with_superclass22ConformsToSillyDefaultCAA0fG0A2aDP5makeTSiyFTW
251+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)