]> Cypherpunks.ru repositories - gostls13.git/blob - test/typeparam/dictionaryCapture.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / typeparam / dictionaryCapture.go
1 // run
2
3 // Copyright 2021 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Test situations where functions/methods are not
8 // immediately called and we need to capture the dictionary
9 // required for later invocation.
10
11 package main
12
13 import (
14         "fmt"
15 )
16
17 func main() {
18         functions()
19         methodExpressions()
20         genMethodExpressions[int](7)
21         methodValues()
22         genMethodValues[int](7)
23         interfaceMethods()
24         globals()
25         recursive()
26 }
27
28 func g0[T any](x T) {
29 }
30 func g1[T any](x T) T {
31         return x
32 }
33 func g2[T any](x T) (T, T) {
34         return x, x
35 }
36
37 func functions() {
38         f0 := g0[int]
39         f0(7)
40         f1 := g1[int]
41         is7(f1(7))
42         f2 := g2[int]
43         is77(f2(7))
44 }
45
46 func is7(x int) {
47         if x != 7 {
48                 println(x)
49                 panic("assertion failed")
50         }
51 }
52 func is77(x, y int) {
53         if x != 7 || y != 7 {
54                 println(x, y)
55                 panic("assertion failed")
56         }
57 }
58
59 type s[T any] struct {
60         a T
61 }
62
63 func (x s[T]) g0() {
64 }
65 func (x s[T]) g1() T {
66         return x.a
67 }
68 func (x s[T]) g2() (T, T) {
69         return x.a, x.a
70 }
71
72 func methodExpressions() {
73         x := s[int]{a: 7}
74         f0 := s[int].g0
75         f0(x)
76         f0p := (*s[int]).g0
77         f0p(&x)
78         f1 := s[int].g1
79         is7(f1(x))
80         f1p := (*s[int]).g1
81         is7(f1p(&x))
82         f2 := s[int].g2
83         is77(f2(x))
84         f2p := (*s[int]).g2
85         is77(f2p(&x))
86 }
87
88 func genMethodExpressions[T comparable](want T) {
89         x := s[T]{a: want}
90         f0 := s[T].g0
91         f0(x)
92         f0p := (*s[T]).g0
93         f0p(&x)
94         f1 := s[T].g1
95         if got := f1(x); got != want {
96                 panic(fmt.Sprintf("f1(x) == %d, want %d", got, want))
97         }
98         f1p := (*s[T]).g1
99         if got := f1p(&x); got != want {
100                 panic(fmt.Sprintf("f1p(&x) == %d, want %d", got, want))
101         }
102         f2 := s[T].g2
103         if got1, got2 := f2(x); got1 != want || got2 != want {
104                 panic(fmt.Sprintf("f2(x) == %d, %d, want %d, %d", got1, got2, want, want))
105         }
106 }
107
108 func methodValues() {
109         x := s[int]{a: 7}
110         f0 := x.g0
111         f0()
112         f1 := x.g1
113         is7(f1())
114         f2 := x.g2
115         is77(f2())
116 }
117
118 func genMethodValues[T comparable](want T) {
119         x := s[T]{a: want}
120         f0 := x.g0
121         f0()
122         f1 := x.g1
123         if got := f1(); got != want {
124                 panic(fmt.Sprintf("f1() == %d, want %d", got, want))
125         }
126         f2 := x.g2
127         if got1, got2 := f2(); got1 != want || got2 != want {
128                 panic(fmt.Sprintf("f2() == %d, %d, want %d, %d", got1, got2, want, want))
129         }
130 }
131
132 var x interface {
133         g0()
134         g1() int
135         g2() (int, int)
136 } = s[int]{a: 7}
137 var y interface{} = s[int]{a: 7}
138
139 func interfaceMethods() {
140         x.g0()
141         is7(x.g1())
142         is77(x.g2())
143         y.(interface{ g0() }).g0()
144         is7(y.(interface{ g1() int }).g1())
145         is77(y.(interface{ g2() (int, int) }).g2())
146 }
147
148 // Also check for instantiations outside functions.
149 var gg0 = g0[int]
150 var gg1 = g1[int]
151 var gg2 = g2[int]
152
153 var hh0 = s[int].g0
154 var hh1 = s[int].g1
155 var hh2 = s[int].g2
156
157 var xtop = s[int]{a: 7}
158 var ii0 = x.g0
159 var ii1 = x.g1
160 var ii2 = x.g2
161
162 func globals() {
163         gg0(7)
164         is7(gg1(7))
165         is77(gg2(7))
166         x := s[int]{a: 7}
167         hh0(x)
168         is7(hh1(x))
169         is77(hh2(x))
170         ii0()
171         is7(ii1())
172         is77(ii2())
173 }
174
175 func recursive() {
176         if got, want := recur1[int](5), 110; got != want {
177                 panic(fmt.Sprintf("recur1[int](5) = %d, want = %d", got, want))
178         }
179 }
180
181 type Integer interface {
182         int | int32 | int64
183 }
184
185 func recur1[T Integer](n T) T {
186         if n == 0 || n == 1 {
187                 return T(1)
188         } else {
189                 return n * recur2(n-1)
190         }
191 }
192
193 func recur2[T Integer](n T) T {
194         list := make([]T, n)
195         for i, _ := range list {
196                 list[i] = T(i + 1)
197         }
198         var sum T
199         for _, elt := range list {
200                 sum += elt
201         }
202         return sum + recur1(n-1)
203 }