Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / go / pointer / testdata / interfaces.go
1 // +build ignore
2
3 package main
4
5 type I interface {
6         f()
7 }
8
9 type C int
10
11 func (*C) f() {}
12
13 type D struct{ ptr *int }
14
15 func (D) f() {}
16
17 type E struct{}
18
19 func (*E) f() {}
20
21 var a, b int
22
23 var unknown bool // defeat dead-code elimination
24
25 func interface1() {
26         var i interface{} = &a
27         var j interface{} = D{&b}
28         k := j
29         if unknown {
30                 k = i
31         }
32
33         print(i) // @types *int
34         print(j) // @types D
35         print(k) // @types *int | D
36
37         print(i.(*int)) // @pointsto main.a
38         print(j.(*int)) // @pointsto
39         print(k.(*int)) // @pointsto main.a
40
41         print(i.(D).ptr) // @pointsto
42         print(j.(D).ptr) // @pointsto main.b
43         print(k.(D).ptr) // @pointsto main.b
44 }
45
46 func interface2() {
47         var i I = (*C)(&a)
48         var j I = D{&a}
49         k := j
50         if unknown {
51                 k = i
52         }
53
54         print(i) // @types *C
55         print(j) // @types D
56         print(k) // @types *C | D
57         print(k) // @pointsto makeinterface:main.D | makeinterface:*main.C
58
59         k.f()
60         // @calls main.interface2 -> (*main.C).f
61         // @calls main.interface2 -> (main.D).f
62
63         print(i.(*C))    // @pointsto main.a
64         print(j.(D).ptr) // @pointsto main.a
65         print(k.(*C))    // @pointsto main.a
66
67         switch x := k.(type) {
68         case *C:
69                 print(x) // @pointsto main.a
70         case D:
71                 print(x.ptr) // @pointsto main.a
72         case *E:
73                 print(x) // @pointsto
74         }
75 }
76
77 func interface3() {
78         // There should be no backflow of concrete types from the type-switch to x.
79         var x interface{} = 0
80         print(x) // @types int
81         switch x.(type) {
82         case int:
83         case string:
84         }
85 }
86
87 func interface4() {
88         var i interface{} = D{&a}
89         if unknown {
90                 i = 123
91         }
92
93         print(i) // @types int | D
94
95         j := i.(I)       // interface narrowing type-assertion
96         print(j)         // @types D
97         print(j.(D).ptr) // @pointsto main.a
98
99         var l interface{} = j // interface widening assignment.
100         print(l)              // @types D
101         print(l.(D).ptr)      // @pointsto main.a
102
103         m := j.(interface{}) // interface widening type-assertion.
104         print(m)             // @types D
105         print(m.(D).ptr)     // @pointsto main.a
106 }
107
108 // Interface method calls and value flow:
109
110 type J interface {
111         f(*int) *int
112 }
113
114 type P struct {
115         x int
116 }
117
118 func (p *P) f(pi *int) *int {
119         print(p)  // @pointsto p@i5p:6
120         print(pi) // @pointsto i@i5i:6
121         return &p.x
122 }
123
124 func interface5() {
125         var p P // @line i5p
126         var j J = &p
127         var i int      // @line i5i
128         print(j.f(&i)) // @pointsto p.x@i5p:6
129         print(&i)      // @pointsto i@i5i:6
130
131         print(j) // @pointsto makeinterface:*main.P
132 }
133
134 // @calls main.interface5 -> (*main.P).f
135
136 func interface6() {
137         f := I.f
138         print(f) // @pointsto (main.I).f$thunk
139         f(new(struct{ D }))
140 }
141
142 // @calls main.interface6 -> (main.I).f$thunk
143 // @calls (main.I).f$thunk -> (*struct{main.D}).f
144
145 func main() {
146         interface1()
147         interface2()
148         interface3()
149         interface4()
150         interface5()
151         interface6()
152 }