File: ranking.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (442 lines) | stat: -rw-r--r-- 16,553 bytes parent folder | download
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
// RUN: %target-swift-emit-silgen %s -verify -swift-version 5 | %FileCheck %s

protocol P {
  var p: P { get set }
  var q: P? { get set }
  func p(_: P)
  func q(_: P)
}

struct S : P {
  var p: P
  var q: P?
  func p(_: P) {}
  func q(_: P) {}
}

class Base : P {
  var p: P
  var q: P?
  func p(_: P) {}
  func q(_: P) {}
  init(_ p: P) { self.p = p }
}

class Derived : Base {
}

func genericOverload<T>(_: T) {}
func genericOverload<T>(_: T?) {}
func genericOptional<T>(_: T?) {}
func genericNoOptional<T>(_: T) {}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking22propertyVersusFunctionyyAA1P_p_xtAaCRzlF
func propertyVersusFunction<T : P>(_ p: P, _ t: T) {
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.p!getter
  let _ = p.p
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.p!getter
  let _: P = p.p
  // CHECK: function_ref @$s7ranking22propertyVersusFunctionyyAA1P_p_xtAaCRzlFyAaC_pcAaC_pcfu_ : $@convention(thin) (@in_guaranteed any P) -> @owned @callee_guaranteed (@in_guaranteed any P) -> ()
  let _: (P) -> () = p.p
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.p!getter
  let _: P? = p.p
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.p!getter
  let _: Any = p.p
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.p!getter
  let _: Any? = p.p

  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.p!getter
  // CHECK: function_ref @$s7ranking15genericOverloadyyxlF
  genericOverload(p.p)
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.q!getter
  // CHECK: function_ref @$s7ranking15genericOverloadyyxSglF
  genericOverload(p.q)
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.p!getter
  // CHECK: function_ref @$s7ranking15genericOptionalyyxSglF
  genericOptional(p.p)
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.q!getter
  // CHECK: function_ref @$s7ranking15genericOptionalyyxSglF
  genericOptional(p.q)
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.p!getter
  // CHECK: function_ref @$s7ranking17genericNoOptionalyyxlF
  genericNoOptional(p.p)
  // CHECK: witness_method $@opened("{{.*}}", any P) Self, #P.q!getter
  // CHECK: function_ref @$s7ranking17genericNoOptionalyyxlF
  genericNoOptional(p.q)

  // CHECK: witness_method $T, #P.p!getter
  let _ = t.p
  // CHECK: witness_method $T, #P.p!getter
  let _: P = t.p
  // CHECK: function_ref @$s7ranking22propertyVersusFunctionyyAA1P_p_xtAaCRzlFyAaC_pcxcfu1_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed (@in_guaranteed any P) -> ()
  let _: (P) -> () = t.p
  // CHECK: witness_method $T, #P.p!getter
  let _: P? = t.p
  // CHECK: witness_method $T, #P.p!getter
  let _: Any = t.p
  // CHECK: witness_method $T, #P.p!getter
  let _: Any? = t.p

  // CHECK: witness_method $T, #P.p!getter
  // CHECK: function_ref @$s7ranking15genericOverloadyyxlF
  genericOverload(t.p)
  // CHECK: witness_method $T, #P.q!getter
  // CHECK: function_ref @$s7ranking15genericOverloadyyxSglF
  genericOverload(t.q)
  // CHECK: witness_method $T, #P.p!getter
  // CHECK: function_ref @$s7ranking15genericOptionalyyxSglF
  genericOptional(t.p)
  // CHECK: witness_method $T, #P.q!getter
  // CHECK: function_ref @$s7ranking15genericOptionalyyxSglF
  genericOptional(t.q)
  // CHECK: witness_method $T, #P.p!getter
  // CHECK: function_ref @$s7ranking17genericNoOptionalyyxlF
  genericNoOptional(t.p)
  // CHECK: witness_method $T, #P.q!getter
  // CHECK: function_ref @$s7ranking17genericNoOptionalyyxlF
  genericNoOptional(t.q)
}

extension P {
  func propertyVersusFunction() {
    // CHECK: witness_method $Self, #P.p!getter
    let _ = self.p
    // CHECK: witness_method $Self, #P.p!getter
    let _: P = self.p
    // CHECK: function_ref @$s7ranking1PPAAE22propertyVersusFunctionyyFyAaB_pcxcfu_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed (@in_guaranteed any P) -> ()
    let _: (P) -> () = self.p
    // CHECK: witness_method $Self, #P.p!getter
    let _: P? = self.p
    // CHECK: witness_method $Self, #P.p!getter
    let _: Any = self.p
    // CHECK: witness_method $Self, #P.p!getter
    let _: Any? = self.p

    // CHECK: witness_method $Self, #P.p!getter
    // CHECK: function_ref @$s7ranking15genericOverloadyyxlF
    genericOverload(self.p)
    // CHECK: witness_method $Self, #P.q!getter
    // CHECK: function_ref @$s7ranking15genericOverloadyyxSglF
    genericOverload(self.q)
    // CHECK: witness_method $Self, #P.p!getter
    // CHECK: function_ref @$s7ranking15genericOptionalyyxSglF
    genericOptional(self.p)
    // CHECK: witness_method $Self, #P.q!getter
    // CHECK: function_ref @$s7ranking15genericOptionalyyxSglF
    genericOptional(self.q)
    // CHECK: witness_method $Self, #P.p!getter
    // CHECK: function_ref @$s7ranking17genericNoOptionalyyxlF
    genericNoOptional(self.p)
    // CHECK: witness_method $Self, #P.q!getter
    // CHECK: function_ref @$s7ranking17genericNoOptionalyyxlF
    genericNoOptional(self.q)
  }
}

//--------------------------------------------------------------------

func f0<T>(_ x: T) {}

// FIXME: Lookup breaks if these come after f1!
class A { 
  init() {} 
};
class B : A { 
  override init() { super.init() } 
}

func f1(_ a: A) -> A { return a }
func f1(_ b: B) -> B { return b }

func testDerived(b: B) {
  // CHECK-LABEL: sil hidden [ossa] @$s7ranking11testDerived1byAA1BC_tF
  // CHECK: function_ref @$s7ranking2f1yAA1BCADF
  // CHECK: function_ref @$s7ranking2f0yyxlF
  f0(f1(b))
  // CHECK: end sil function '$s7ranking11testDerived1byAA1BC_tF'
}

protocol X {
  var foo: Int { get }
  var bar: Int { get }
  func baz() -> Int
  subscript(foo: String) -> Int { get }
}

class Y {
  var foo: Int = 0
  func baz() -> Int { return foo }
  subscript(foo: String) -> Int { return 0 }
}
extension Y {
  var bar: Int { return foo }
}

protocol Z : Y {
  var foo: Int { get }
  var bar: Int { get }
  func baz() -> Int
  subscript(foo: String) -> Int { get }
}

class GenericClass<T> {
  var foo: T
  init(_ foo: T) { self.foo = foo }
  func baz() -> T { return foo }
}
extension GenericClass {
  var bar: T { return foo }
  subscript(foo: String) -> Int { return 0 }
}

// Make sure we favour the class implementation over the protocol requirement.

// CHECK-LABEL: sil hidden [ossa] @$s7ranking32testGenericPropertyProtocolClassyyxAA1YCRbzAA1XRzlF
func testGenericPropertyProtocolClass<T : X & Y>(_ t: T) {
  _ = t.foo   // CHECK: class_method {{%.*}} : $Y, #Y.foo!getter
  _ = t.bar   // CHECK: function_ref @$s7ranking1YC3barSivg
  _ = t.baz() // CHECK: class_method {{%.*}} : $Y, #Y.baz
  _ = t[""]   // CHECK: class_method {{%.*}} : $Y, #Y.subscript!getter
}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking36testExistentialPropertyProtocolClassyyAA1X_AA1YCXcF
func testExistentialPropertyProtocolClass(_ t: X & Y) {
  _ = t.foo   // CHECK: class_method {{%.*}} : $Y, #Y.foo!getter
  _ = t.bar   // CHECK: function_ref @$s7ranking1YC3barSivg
  _ = t.baz() // CHECK: class_method {{%.*}} : $Y, #Y.baz
  _ = t[""]   // CHECK: class_method {{%.*}} : $Y, #Y.subscript!getter
}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking46testGenericPropertySubclassConstrainedProtocolyyxAA1ZRzlF
func testGenericPropertySubclassConstrainedProtocol<T : Z>(_ t: T) {
  _ = t.foo   // CHECK: class_method {{%.*}} : $Y, #Y.foo!getter
  _ = t.bar   // CHECK: function_ref @$s7ranking1YC3barSivg
  _ = t.baz() // CHECK: class_method {{%.*}} : $Y, #Y.baz
  _ = t[""]   // CHECK: class_method {{%.*}} : $Y, #Y.subscript!getter
}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking50testExistentialPropertySubclassConstrainedProtocolyyAA1Z_pF
func testExistentialPropertySubclassConstrainedProtocol(_ t: Z) {
  _ = t.foo   // CHECK: class_method {{%.*}} : $Y, #Y.foo!getter
  _ = t.bar   // CHECK: function_ref @$s7ranking1YC3barSivg
  _ = t.baz() // CHECK: class_method {{%.*}} : $Y, #Y.baz
  _ = t[""]   // CHECK: class_method {{%.*}} : $Y, #Y.subscript!getter
}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking43testExistentialPropertyProtocolGenericClassyyAA1X_AA0fG0CySiGXcF
func testExistentialPropertyProtocolGenericClass(_ t: GenericClass<Int> & X) {
  _ = t.foo   // CHECK: class_method {{%.*}} : $GenericClass<Int>, #GenericClass.foo!getter
  _ = t.bar   // CHECK: function_ref @$s7ranking12GenericClassC3barxvg
  _ = t.baz() // CHECK: class_method {{%.*}} : $GenericClass<Int>, #GenericClass.baz
  _ = t[""]   // CHECK: function_ref @$s7ranking12GenericClassCySiSScig
}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking43testExistentialPropertyProtocolGenericClassyyAA1X_AA0fG0CySSGXcF
func testExistentialPropertyProtocolGenericClass(_ t: GenericClass<String> & X) {
  _ = t.foo   // CHECK: class_method {{%.*}} : $GenericClass<String>, #GenericClass.foo!getter
  _ = t.bar   // CHECK: function_ref @$s7ranking12GenericClassC3barxvg
  _ = t.baz() // CHECK: class_method {{%.*}} : $GenericClass<String>, #GenericClass.baz
  _ = t[""]   // CHECK: function_ref @$s7ranking12GenericClassCySiSScig
}

extension X where Self : Y {
  // CHECK-LABEL: sil hidden [ossa] @$s7ranking1XPA2A1YCRbzrlE32testGenericPropertyProtocolClassyyxF
  func testGenericPropertyProtocolClass(_ x: Self) {
    _ = self.foo   // CHECK: class_method {{%.*}} : $Y, #Y.foo!getter
    _ = self.bar   // CHECK: function_ref @$s7ranking1YC3barSivg
    _ = self.baz() // CHECK: class_method {{%.*}} : $Y, #Y.baz
    _ = self[""]   // CHECK: class_method {{%.*}} : $Y, #Y.subscript!getter
  }
}

extension X where Self : GenericClass<Int> {
  // CHECK-LABEL: sil hidden [ossa] @$s7ranking1XPA2A12GenericClassCySiGRbzrlE04testb16PropertyProtocolbC0yyxF
  func testGenericPropertyProtocolGenericClass(_ x: Self) {
    _ = self.foo   // CHECK: class_method {{%.*}} : $GenericClass<Int>, #GenericClass.foo!getter
    _ = self.bar   // CHECK: function_ref @$s7ranking12GenericClassC3barxvg
    _ = self.baz() // CHECK: class_method {{%.*}} : $GenericClass<Int>, #GenericClass.baz
    _ = self[""]   // CHECK: function_ref @$s7ranking12GenericClassCySiSScig
  }
}

extension X where Self : GenericClass<String> {
  // CHECK-LABEL: sil hidden [ossa] @$s7ranking1XPA2A12GenericClassCySSGRbzrlE04testb16PropertyProtocolbC0yyxF
  func testGenericPropertyProtocolGenericClass(_ x: Self) {
    _ = self.foo   // CHECK: class_method {{%.*}} : $GenericClass<String>, #GenericClass.foo!getter
    _ = self.bar   // CHECK: function_ref @$s7ranking12GenericClassC3barxvg
    _ = self.baz() // CHECK: class_method {{%.*}} : $GenericClass<String>, #GenericClass.baz
    _ = self[""]   // CHECK: function_ref @$s7ranking12GenericClassCySiSScig
  }
}

//--------------------------------------------------------------------
// Constructor-specific ranking
//--------------------------------------------------------------------

// We have a special ranking rule that only currently applies to constructors,
// and compares the concrete parameter types.

protocol Q {
  init()
}

struct S1<T : Q> {
  // We want to prefer the non-optional init over the optional init here.
  init(_ x: T = .init()) {}
  init(_ x: T? = nil) {}

  // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S1V11testRankingACyxGyt_tcfC
  init(testRanking: Void) {
    // CHECK: function_ref @$s7ranking2S1VyACyxGxcfC : $@convention(method) <τ_0_0 where τ_0_0 : Q> (@in τ_0_0, @thin S1<τ_0_0>.Type) -> S1<τ_0_0>
    self.init()
  }

  // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S1V15testInitRankingyyF
  func testInitRanking() {
    // CHECK: function_ref @$s7ranking2S1VyACyxGxcfC : $@convention(method) <τ_0_0 where τ_0_0 : Q> (@in τ_0_0, @thin S1<τ_0_0>.Type) -> S1<τ_0_0>
    _ = S1<T>()
  }
}

protocol R {}
extension Array : R {}
extension Int : R {}

struct S2 {
  init(_ x: R) {}
  init(_ x: Int...) {}

  // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S2V15testInitRankingyyF
  func testInitRanking() {
    // We currently prefer the non-variadic init due to having
    // "less effective parameters", and we don't compare the types for ranking due
    // to the difference in variadic-ness.
    // CHECK: function_ref @$s7ranking2S2VyAcA1R_pcfC : $@convention(method) (@in any R, @thin S2.Type) -> S2
    _ = S2(0)
  }
}

// Very cursed: As a holdover from how we used to represent function inputs,
// we rank these as tuples and consider (x:x:) to be a subtype of (x:y:). Seems
// unlikely this is being relied on in the real world, but let's at least have
// it as a test case to track its behavior.
struct S3 {
  init(x _: Int = 0, y _: Int = 0) {}
  init(x _: Int = 0, x _: Int = 0) {}

  func testInitRanking() {
    // CHECK: function_ref @$s7ranking2S3V1xAdCSi_SitcfC : $@convention(method) (Int, Int, @thin S3.Type) -> S3
    _ = S3()
  }
}

// Also another consequence of having ranked as tuples: we prefer the unlabeled
// init here.
struct S4 {
  init(x: Int = 0, y: Int = 0) {}
  init(_ x: Int = 0, _ y: Int = 0) {}

  // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S4V15testInitRankingyyF
  func testInitRanking() {
    // CHECK: function_ref @$s7ranking2S4VyACSi_SitcfC : $@convention(method) (Int, Int, @thin S4.Type) -> S4
    _ = S4()
  }
}

// rdar://84279742 – Make sure we prefer the unlabeled init here.
struct S5 {
  init(x: Int...) {}
  init(_ x: Int...) {}

  // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S5V15testInitRankingyyF
  func testInitRanking() {
    // CHECK: function_ref @$s7ranking2S5VyACSid_tcfC : $@convention(method) (@owned Array<Int>, @thin S5.Type) -> S5
    _ = S5()
  }
}

// We should also prefer the unlabeled case here.
struct S6 {
  init(_: Int = 0, x: Int...) {}
  init(_: Int = 0, _: Int...) {}

  // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S6V15testInitRankingyyF
  func testInitRanking() {
    // CHECK: function_ref @$s7ranking2S6VyACSi_SidtcfC : $@convention(method) (Int, @owned Array<Int>, @thin S6.Type) -> S6
    _ = S6()
  }
}

// However subtyping rules take precedence over labeling rules, so we should
// prefer the labeled init here.
struct S7 {
  init(x: Int...) {}
  init(_: Int?...) {}

  // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S7V15testInitRankingyyF
  func testInitRanking() {
    // CHECK: function_ref @$s7ranking2S7V1xACSid_tcfC : $@convention(method) (@owned Array<Int>, @thin S7.Type) -> S7
    _ = S7()
  }
}

// Subtyping rules also let us prefer the Int... init here.
struct S8 {
  init(_: Int?...) {}
  init(_: Int...) {}

  // CHECK-LABEL: sil hidden [ossa] @$s7ranking2S8V15testInitRankingyyF
  func testInitRanking() {
    // CHECK: function_ref @$s7ranking2S8VyACSid_tcfC : $@convention(method) (@owned Array<Int>, @thin S8.Type) -> S8
    _ = S8()
  }
}

//--------------------------------------------------------------------
// Pointer conversions
//--------------------------------------------------------------------

struct UnsafePointerStruct {
  // CHECK-LABEL: sil hidden [ossa] @$s7ranking19UnsafePointerStructVyACSPyxGSgclufC : $@convention(method) <U> (Optional<UnsafePointer<U>>, @thin UnsafePointerStruct.Type) -> UnsafePointerStruct
  init<U>(_ from: UnsafePointer<U>) {}
  init<U>(_ from: UnsafePointer<U>?) {
    // CHECK: function_ref @$s7ranking19UnsafePointerStructVyACSPyxGclufC : $@convention(method) <τ_0_0> (UnsafePointer<τ_0_0>, @thin UnsafePointerStruct.Type) -> UnsafePointerStruct
    self.init(from!)
  }
}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking22useUnsafePointerStructyySPyxGlF : $@convention(thin) <U> (UnsafePointer<U>) -> ()
func useUnsafePointerStruct<U>(_ ptr: UnsafePointer<U>) {
  // CHECK: function_ref @$s7ranking19UnsafePointerStructVyACSPyxGclufC : $@convention(method) <τ_0_0> (UnsafePointer<τ_0_0>, @thin UnsafePointerStruct.Type) -> UnsafePointerStruct
  let _: UnsafePointerStruct = UnsafePointerStruct(ptr)
}

/// Archetype vs. non-archetype (expect placeholder)

protocol SignalProtocol {
  associatedtype Element
  associatedtype Error: Swift.Error
}

struct Signal<Element, Error: Swift.Error>: SignalProtocol {
  init<S: Sequence>(sequence: S) where S.Iterator.Element == Element {
  }
}

extension SignalProtocol where Element: SignalProtocol, Element.Error == Error {
  typealias InnerElement = Element.Element

  func flatten() -> Signal<InnerElement, Error> {
    fatalError()
  }
}

extension SignalProtocol where Element: SignalProtocol, Error == Never {
  func flatten() -> Signal<Element.Element, Element.Error> {
    fatalError()
  }
}

func no_ambiguity_error_vs_never<Element, Error>(_ signals: [Signal<Element, Error>]) -> Signal<Element, Error> {
  return Signal(sequence: signals).flatten() // Ok
}