Source file
src/go/types/api_typeparams_test.go
1
2
3
4
5
6
7
8 package types_test
9
10 import (
11 "fmt"
12 "go/ast"
13 "testing"
14
15 . "go/types"
16 )
17
18 func TestInferredInfo(t *testing.T) {
19 var tests = []struct {
20 src string
21 fun string
22 targs []string
23 sig string
24 }{
25 {genericPkg + `p0; func f[T any](T); func _() { f(42) }`,
26 `f`,
27 []string{`int`},
28 `func(int)`,
29 },
30 {genericPkg + `p1; func f[T any](T) T; func _() { f('@') }`,
31 `f`,
32 []string{`rune`},
33 `func(rune) rune`,
34 },
35 {genericPkg + `p2; func f[T any](...T) T; func _() { f(0i) }`,
36 `f`,
37 []string{`complex128`},
38 `func(...complex128) complex128`,
39 },
40 {genericPkg + `p3; func f[A, B, C any](A, *B, []C); func _() { f(1.2, new(string), []byte{}) }`,
41 `f`,
42 []string{`float64`, `string`, `byte`},
43 `func(float64, *string, []byte)`,
44 },
45 {genericPkg + `p4; func f[A, B any](A, *B, ...[]B); func _() { f(1.2, new(byte)) }`,
46 `f`,
47 []string{`float64`, `byte`},
48 `func(float64, *byte, ...[]byte)`,
49 },
50
51 {genericPkg + `s1; func f[T any, P interface{type *T}](x T); func _(x string) { f(x) }`,
52 `f`,
53 []string{`string`, `*string`},
54 `func(x string)`,
55 },
56 {genericPkg + `s2; func f[T any, P interface{type *T}](x []T); func _(x []int) { f(x) }`,
57 `f`,
58 []string{`int`, `*int`},
59 `func(x []int)`,
60 },
61 {genericPkg + `s3; type C[T any] interface{type chan<- T}; func f[T any, P C[T]](x []T); func _(x []int) { f(x) }`,
62 `f`,
63 []string{`int`, `chan<- int`},
64 `func(x []int)`,
65 },
66 {genericPkg + `s4; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]](x []T); func _(x []int) { f(x) }`,
67 `f`,
68 []string{`int`, `chan<- int`, `chan<- []*chan<- int`},
69 `func(x []int)`,
70 },
71
72 {genericPkg + `t1; func f[T any, P interface{type *T}]() T; func _() { _ = f[string] }`,
73 `f`,
74 []string{`string`, `*string`},
75 `func() string`,
76 },
77 {genericPkg + `t2; type C[T any] interface{type chan<- T}; func f[T any, P C[T]]() []T; func _() { _ = f[int] }`,
78 `f`,
79 []string{`int`, `chan<- int`},
80 `func() []int`,
81 },
82 {genericPkg + `t3; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]]() []T; func _() { _ = f[int] }`,
83 `f`,
84 []string{`int`, `chan<- int`, `chan<- []*chan<- int`},
85 `func() []int`,
86 },
87 }
88
89 for _, test := range tests {
90 info := Info{}
91 info.Inferred = make(map[ast.Expr]Inferred)
92 name, err := mayTypecheck(t, "InferredInfo", test.src, &info)
93 if err != nil {
94 t.Errorf("package %s: %v", name, err)
95 continue
96 }
97
98
99 var targs []Type
100 var sig *Signature
101 for call, inf := range info.Inferred {
102 var fun ast.Expr
103 switch x := call.(type) {
104 case *ast.CallExpr:
105 fun = x.Fun
106 case *ast.IndexExpr:
107 fun = x.X
108 default:
109 panic(fmt.Sprintf("unexpected call expression type %T", call))
110 }
111 if ExprString(fun) == test.fun {
112 targs = inf.Targs
113 sig = inf.Sig
114 break
115 }
116 }
117 if targs == nil {
118 t.Errorf("package %s: no inferred information found for %s", name, test.fun)
119 continue
120 }
121
122
123 if len(targs) != len(test.targs) {
124 t.Errorf("package %s: got %d type arguments; want %d", name, len(targs), len(test.targs))
125 continue
126 }
127 for i, targ := range targs {
128 if got := targ.String(); got != test.targs[i] {
129 t.Errorf("package %s, %d. type argument: got %s; want %s", name, i, got, test.targs[i])
130 continue
131 }
132 }
133
134
135 if got := sig.String(); got != test.sig {
136 t.Errorf("package %s: got %s; want %s", name, got, test.sig)
137 }
138 }
139 }
140
View as plain text