File: devirt_contravariant_args.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 (89 lines) | stat: -rw-r--r-- 1,758 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
// RUN: %target-swift-frontend -O -primary-file %s -emit-sil -sil-inline-threshold 1000 -sil-verify-all | %FileCheck %s

// Make sure that we can dig all the way through the class hierarchy and
// protocol conformances.

// CHECK-LABEL: sil hidden @$s25devirt_contravariant_args6driveryyF : $@convention(thin) () -> () {
// CHECK: function_ref unknownC2
// CHECK: function_ref unknownC1
// CHECK: function_ref unknownC0
// CHECK: return
// CHECK-NEXT: }

@_silgen_name("unknownC0")
func unknownC0(_ c : C0) -> ()
@_silgen_name("unknownC1")
func unknownC1(_ c : C1) -> ()
@_silgen_name("unknownC2")
func unknownC2(_ c : C2) -> ()

protocol P {}

class C0 : P {}
class C1 : C0 {}
class C2 : C1 {}

class B<T> {
  func performSomething(_ p : P) {
    doSomething(p as! C2)
  }

  func doSomething(_ c : C2) {
    unknownC2(c)
  }

  // See comment in protocol P
  //class func doSomethingMeta() {
  //  unknown1b()
  //}
}

class B2<T> : B<T> {
  override func performSomething(_ p : P) {
    doSomething(p as! C1)
  }

  // When we have covariance in protocols, change this to B2.
  // We do not specialize typealias correctly now.
  //typealias X = B
  override func doSomething(_ c : C1) {
    unknownC1(c)
  }

  // See comment in protocol P
  //override class func doSomethingMeta() {
  //  unknown2b()
  //}
}

class B3<T> : B2<T> {
  override func performSomething(_ p : P) {
    doSomething(p as! C0)
  }

  override func doSomething(_ c : C0) {
    unknownC0(c)
  }
}



func doSomething<T : P>(_ b : B<T>, _ t : T) {
  b.performSomething(t)
}

func driver() -> () {
  let b = B<C2>()
  let b2 = B2<C1>()
  let b3 = B3<C0>()

  let c0 = C0()
  let c1 = C1()
  let c2 = C2()

  doSomething(b, c2)
  doSomething(b2, c1)
  doSomething(b3, c0)
}

driver()