@@ -269,6 +269,80 @@ extension X where Self : GenericClass<String> {
269
269
}
270
270
}
271
271
272
+ //--------------------------------------------------------------------
273
+ // Constructor-specific ranking
274
+ //--------------------------------------------------------------------
275
+
276
+ // We have a special ranking rule that only currently applies to constructors,
277
+ // and compares the concrete parameter types.
278
+
279
+ protocol Q {
280
+ init ( )
281
+ }
282
+
283
+ struct S1 < T : Q > {
284
+ // We want to prefer the non-optional init over the optional init here.
285
+ init ( _ x: T = . init( ) ) { }
286
+ init ( _ x: T ? = nil ) { }
287
+
288
+ // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S1V11testRankingACyxGyt_tcfC
289
+ init ( testRanking: Void ) {
290
+ // CHECK: function_ref @$s7ranking2S1VyACyxGxcfC : $@convention(method) <τ_0_0 where τ_0_0 : Q> (@in τ_0_0, @thin S1<τ_0_0>.Type) -> S1<τ_0_0>
291
+ self . init ( )
292
+ }
293
+
294
+ // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S1V15testInitRankingyyF
295
+ func testInitRanking( ) {
296
+ // CHECK: function_ref @$s7ranking2S1VyACyxGxcfC : $@convention(method) <τ_0_0 where τ_0_0 : Q> (@in τ_0_0, @thin S1<τ_0_0>.Type) -> S1<τ_0_0>
297
+ _ = S1 < T > ( )
298
+ }
299
+ }
300
+
301
+ protocol R { }
302
+ extension Array : R { }
303
+ extension Int : R { }
304
+
305
+ struct S2 {
306
+ init ( _ x: R ) { }
307
+ init ( _ x: Int ... ) { }
308
+
309
+ // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S2V15testInitRankingyyF
310
+ func testInitRanking( ) {
311
+ // We currently prefer the non-variadic init due to having
312
+ // "less effective parameters", and we don't compare the types for ranking due
313
+ // to the difference in variadic-ness.
314
+ // CHECK: function_ref @$s7ranking2S2VyAcA1R_pcfC : $@convention(method) (@in R, @thin S2.Type) -> S2
315
+ _ = S2 ( 0 )
316
+ }
317
+ }
318
+
319
+ // Very cursed: As a holdover from how we used to represent function inputs,
320
+ // we rank these as tuples and consider (x:x:) to be a subtype of (x:y:). Seems
321
+ // unlikely this is being relied on in the real world, but let's at least have
322
+ // it as a test case to track its behavior.
323
+ struct S3 {
324
+ init ( x _: Int = 0 , y _: Int = 0 ) { }
325
+ init ( x _: Int = 0 , x _: Int = 0 ) { }
326
+
327
+ func testInitRanking( ) {
328
+ // CHECK: function_ref @$s7ranking2S3V1xAdCSi_SitcfC : $@convention(method) (Int, Int, @thin S3.Type) -> S3
329
+ _ = S3 ( )
330
+ }
331
+ }
332
+
333
+ // Also another consequence of having ranked as tuples: we prefer the unlabeled
334
+ // init here.
335
+ struct S4 {
336
+ init ( x: Int = 0 , y: Int = 0 ) { }
337
+ init ( _ x: Int = 0 , _ y: Int = 0 ) { }
338
+
339
+ // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S4V15testInitRankingyyF
340
+ func testInitRanking( ) {
341
+ // CHECK: function_ref @$s7ranking2S4VyACSi_SitcfC : $@convention(method) (Int, Int, @thin S4.Type) -> S4
342
+ _ = S4 ( )
343
+ }
344
+ }
345
+
272
346
//--------------------------------------------------------------------
273
347
// Pointer conversions
274
348
//--------------------------------------------------------------------
0 commit comments