...
Source file
src/go/types/named_test.go
1
2
3
4
5 package types_test
6
7 import (
8 "go/ast"
9 "go/token"
10 "testing"
11
12 . "go/types"
13 )
14
15 func BenchmarkNamed(b *testing.B) {
16 const src = `
17 package p
18
19 type T struct {
20 P int
21 }
22
23 func (T) M(int) {}
24 func (T) N() (i int) { return }
25
26 type G[P any] struct {
27 F P
28 }
29
30 func (G[P]) M(P) {}
31 func (G[P]) N() (p P) { return }
32
33 type Inst = G[int]
34 `
35 pkg := mustTypecheck(src, nil, nil)
36
37 var (
38 T = pkg.Scope().Lookup("T").Type()
39 G = pkg.Scope().Lookup("G").Type()
40 SrcInst = pkg.Scope().Lookup("Inst").Type()
41 UserInst = mustInstantiate(b, G, Typ[Int])
42 )
43
44 tests := []struct {
45 name string
46 typ Type
47 }{
48 {"nongeneric", T},
49 {"generic", G},
50 {"src instance", SrcInst},
51 {"user instance", UserInst},
52 }
53
54 b.Run("Underlying", func(b *testing.B) {
55 for _, test := range tests {
56 b.Run(test.name, func(b *testing.B) {
57
58 _ = test.typ.Underlying()
59 b.ResetTimer()
60 for i := 0; i < b.N; i++ {
61 _ = test.typ.Underlying()
62 }
63 })
64 }
65 })
66
67 b.Run("NewMethodSet", func(b *testing.B) {
68 for _, test := range tests {
69 b.Run(test.name, func(b *testing.B) {
70
71 _ = NewMethodSet(test.typ)
72 b.ResetTimer()
73 for i := 0; i < b.N; i++ {
74 _ = NewMethodSet(test.typ)
75 }
76 })
77 }
78 })
79 }
80
81 func mustInstantiate(tb testing.TB, orig Type, targs ...Type) Type {
82 inst, err := Instantiate(nil, orig, targs, true)
83 if err != nil {
84 tb.Fatal(err)
85 }
86 return inst
87 }
88
89
90 func TestFiniteTypeExpansion(t *testing.T) {
91 const src = `
92 package p
93
94 type Tree[T any] struct {
95 *Node[T]
96 }
97
98 func (*Tree[R]) N(r R) R { return r }
99
100 type Node[T any] struct {
101 *Tree[T]
102 }
103
104 func (Node[Q]) M(Q) {}
105
106 type Inst = *Tree[int]
107 `
108
109 fset := token.NewFileSet()
110 f := mustParse(fset, src)
111 pkg := NewPackage("p", f.Name.Name)
112 if err := NewChecker(nil, fset, pkg, nil).Files([]*ast.File{f}); err != nil {
113 t.Fatal(err)
114 }
115
116 firstFieldType := func(n *Named) *Named {
117 return n.Underlying().(*Struct).Field(0).Type().(*Pointer).Elem().(*Named)
118 }
119
120 Inst := pkg.Scope().Lookup("Inst").Type().(*Pointer).Elem().(*Named)
121 Node := firstFieldType(Inst)
122 Tree := firstFieldType(Node)
123 if !Identical(Inst, Tree) {
124 t.Fatalf("Not a cycle: got %v, want %v", Tree, Inst)
125 }
126 if Inst != Tree {
127 t.Errorf("Duplicate instances in cycle: %s (%p) -> %s (%p) -> %s (%p)", Inst, Inst, Node, Node, Tree, Tree)
128 }
129 }
130
View as plain text