1
2
3
4
5 package types2_test
6
7 import (
8 "testing"
9
10 "cmd/compile/internal/syntax"
11 . "cmd/compile/internal/types2"
12 )
13
14 func BenchmarkNamed(b *testing.B) {
15 const src = `
16 package p
17
18 type T struct {
19 P int
20 }
21
22 func (T) M(int) {}
23 func (T) N() (i int) { return }
24
25 type G[P any] struct {
26 F P
27 }
28
29 func (G[P]) M(P) {}
30 func (G[P]) N() (p P) { return }
31
32 type Inst = G[int]
33 `
34 pkg := mustTypecheck(src, nil, nil)
35
36 var (
37 T = pkg.Scope().Lookup("T").Type()
38 G = pkg.Scope().Lookup("G").Type()
39 SrcInst = pkg.Scope().Lookup("Inst").Type()
40 UserInst = mustInstantiate(b, G, Typ[Int])
41 )
42
43 tests := []struct {
44 name string
45 typ Type
46 }{
47 {"nongeneric", T},
48 {"generic", G},
49 {"src instance", SrcInst},
50 {"user instance", UserInst},
51 }
52
53 b.Run("Underlying", func(b *testing.B) {
54 for _, test := range tests {
55 b.Run(test.name, func(b *testing.B) {
56
57 _ = test.typ.Underlying()
58 b.ResetTimer()
59 for i := 0; i < b.N; i++ {
60 _ = test.typ.Underlying()
61 }
62 })
63 }
64 })
65 }
66
67 func mustInstantiate(tb testing.TB, orig Type, targs ...Type) Type {
68 inst, err := Instantiate(nil, orig, targs, true)
69 if err != nil {
70 tb.Fatal(err)
71 }
72 return inst
73 }
74
75
76 func TestFiniteTypeExpansion(t *testing.T) {
77 const src = `
78 package p
79
80 type Tree[T any] struct {
81 *Node[T]
82 }
83
84 func (*Tree[R]) N(r R) R { return r }
85
86 type Node[T any] struct {
87 *Tree[T]
88 }
89
90 func (Node[Q]) M(Q) {}
91
92 type Inst = *Tree[int]
93 `
94
95 f := mustParse(src)
96 pkg := NewPackage("p", f.PkgName.Value)
97 if err := NewChecker(nil, pkg, nil).Files([]*syntax.File{f}); err != nil {
98 t.Fatal(err)
99 }
100
101 firstFieldType := func(n *Named) *Named {
102 return n.Underlying().(*Struct).Field(0).Type().(*Pointer).Elem().(*Named)
103 }
104
105 Inst := Unalias(pkg.Scope().Lookup("Inst").Type()).(*Pointer).Elem().(*Named)
106 Node := firstFieldType(Inst)
107 Tree := firstFieldType(Node)
108 if !Identical(Inst, Tree) {
109 t.Fatalf("Not a cycle: got %v, want %v", Tree, Inst)
110 }
111 if Inst != Tree {
112 t.Errorf("Duplicate instances in cycle: %s (%p) -> %s (%p) -> %s (%p)", Inst, Inst, Node, Node, Tree, Tree)
113 }
114 }
115
116
117
118
119 func TestMethodOrdering(t *testing.T) {
120 const src = `
121 package p
122
123 type T struct{}
124
125 func (T) a() {}
126 func (T) c() {}
127 func (T) b() {}
128 `
129
130 var methods []string
131 for i := 0; i < 5; i++ {
132
133 pkg := mustTypecheck(src, nil, nil)
134 T := pkg.Scope().Lookup("T").Type().(*Named)
135
136
137 for _, name := range []string{"foo", "bar", "bal"} {
138 m := NewFunc(nopos, pkg, name, nil )
139 T.AddMethod(m)
140 }
141
142
143 if i == 0 {
144
145 methods = make([]string, T.NumMethods())
146 for j := range methods {
147 methods[j] = T.Method(j).Name()
148 }
149 } else {
150
151 if got := T.NumMethods(); got != len(methods) {
152 t.Errorf("got %d methods, want %d", got, len(methods))
153 continue
154 }
155 for j, m := range methods {
156 if got := T.Method(j).Name(); got != m {
157 t.Errorf("got method %s, want %s", got, m)
158 }
159 }
160 }
161 }
162 }
163
View as plain text