1
2
3
4
5 package types2
6
7 import "cmd/compile/internal/syntax"
8
9
10
11
12
13
14 type Signature struct {
15
16
17
18
19 rparams *TypeParamList
20 tparams *TypeParamList
21 scope *Scope
22 recv *Var
23 params *Tuple
24 results *Tuple
25 variadic bool
26 }
27
28
29
30
31
32
33 func NewSignatureType(recv *Var, recvTypeParams, typeParams []*TypeParam, params, results *Tuple, variadic bool) *Signature {
34 if variadic {
35 n := params.Len()
36 if n == 0 {
37 panic("variadic function must have at least one parameter")
38 }
39 if _, ok := params.At(n - 1).typ.(*Slice); !ok {
40 panic("variadic parameter must be of unnamed slice type")
41 }
42 }
43 sig := &Signature{recv: recv, params: params, results: results, variadic: variadic}
44 if len(recvTypeParams) != 0 {
45 if recv == nil {
46 panic("function with receiver type parameters must have a receiver")
47 }
48 sig.rparams = bindTParams(recvTypeParams)
49 }
50 if len(typeParams) != 0 {
51 if recv != nil {
52 panic("function with type parameters cannot have a receiver")
53 }
54 sig.tparams = bindTParams(typeParams)
55 }
56 return sig
57 }
58
59
60
61
62
63
64
65 func (s *Signature) Recv() *Var { return s.recv }
66
67
68 func (s *Signature) TypeParams() *TypeParamList { return s.tparams }
69
70
71 func (s *Signature) SetTypeParams(tparams []*TypeParam) { s.tparams = bindTParams(tparams) }
72
73
74 func (s *Signature) RecvTypeParams() *TypeParamList { return s.rparams }
75
76
77 func (s *Signature) Params() *Tuple { return s.params }
78
79
80 func (s *Signature) Results() *Tuple { return s.results }
81
82
83 func (s *Signature) Variadic() bool { return s.variadic }
84
85 func (s *Signature) Underlying() Type { return s }
86 func (s *Signature) String() string { return TypeString(s, nil) }
87
88
89
90
91
92 func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []*syntax.Field, ftyp *syntax.FuncType) {
93 check.openScope(ftyp, "function")
94 check.scope.isFunc = true
95 check.recordScope(ftyp, check.scope)
96 sig.scope = check.scope
97 defer check.closeScope()
98
99 if recvPar != nil {
100
101
102
103 _, rname, rparams := check.unpackRecv(recvPar.Type, true)
104 if len(rparams) > 0 {
105 tparams := make([]*TypeParam, len(rparams))
106 for i, rparam := range rparams {
107 tparams[i] = check.declareTypeParam(rparam)
108 }
109 sig.rparams = bindTParams(tparams)
110
111
112
113
114
115
116
117 for i, p := range rparams {
118 if p.Value == "_" {
119 if check.recvTParamMap == nil {
120 check.recvTParamMap = make(map[*syntax.Name]*TypeParam)
121 }
122 check.recvTParamMap[p] = tparams[i]
123 }
124 }
125
126
127 var recvTParams []*TypeParam
128 if rname != nil {
129
130
131
132
133 if recv, _ := check.genericType(rname, false).(*Named); recv != nil {
134 recvTParams = recv.TypeParams().list()
135 }
136 }
137
138 if len(tparams) == len(recvTParams) {
139 smap := makeRenameMap(recvTParams, tparams)
140 for i, tpar := range tparams {
141 recvTPar := recvTParams[i]
142 check.mono.recordCanon(tpar, recvTPar)
143
144
145
146 tpar.bound = check.subst(tpar.obj.pos, recvTPar.bound, smap, nil)
147 }
148 } else if len(tparams) < len(recvTParams) {
149
150
151
152
153 got := measure(len(tparams), "type parameter")
154 check.errorf(recvPar, "got %s, but receiver base type declares %d", got, len(recvTParams))
155 }
156 }
157 }
158
159 if tparams != nil {
160
161 check.collectTypeParams(&sig.tparams, tparams)
162 }
163
164
165
166
167 scope := NewScope(check.scope, nopos, nopos, "function body (temp. scope)")
168 var recvList []*Var
169 if recvPar != nil {
170 recvList, _ = check.collectParams(scope, []*syntax.Field{recvPar}, false)
171 }
172 params, variadic := check.collectParams(scope, ftyp.ParamList, true)
173 results, _ := check.collectParams(scope, ftyp.ResultList, false)
174 scope.Squash(func(obj, alt Object) {
175 var err error_
176 err.errorf(obj, "%s redeclared in this block", obj.Name())
177 err.recordAltDecl(alt)
178 check.report(&err)
179 })
180
181 if recvPar != nil {
182
183
184
185 var recv *Var
186 switch len(recvList) {
187 case 0:
188
189 recv = NewParam(nopos, nil, "", Typ[Invalid])
190 default:
191
192 check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
193 fallthrough
194 case 1:
195 recv = recvList[0]
196 }
197 sig.recv = recv
198
199
200
201 check.later(func() {
202 rtyp, _ := deref(recv.typ)
203
204
205
206 if rtyp != Typ[Invalid] {
207 var err string
208 switch T := rtyp.(type) {
209 case *Named:
210 T.resolve(check.bestContext(nil))
211
212
213 if T.TypeArgs() != nil && sig.RecvTypeParams() == nil {
214 check.errorf(recv.pos, "cannot define methods on instantiated type %s", recv.typ)
215 break
216 }
217
218
219
220 if T.obj.pkg != check.pkg {
221 err = "type not defined in this package"
222 if check.conf.CompilerErrorMessages {
223 check.errorf(recv.pos, "cannot define new methods on non-local type %s", recv.typ)
224 err = ""
225 }
226 } else {
227
228
229
230
231 underIs(T, func(u Type) bool {
232 switch u := u.(type) {
233 case *Basic:
234
235 if u.kind == UnsafePointer {
236 err = "unsafe.Pointer"
237 return false
238 }
239 case *Pointer, *Interface:
240 err = "pointer or interface type"
241 return false
242 }
243 return true
244 })
245 }
246 case *Basic:
247 err = "basic or unnamed type"
248 if check.conf.CompilerErrorMessages {
249 check.errorf(recv.pos, "cannot define new methods on non-local type %s", recv.typ)
250 err = ""
251 }
252 default:
253 check.errorf(recv.pos, "invalid receiver type %s", recv.typ)
254 }
255 if err != "" {
256 check.errorf(recv.pos, "invalid receiver type %s (%s)", recv.typ, err)
257 }
258 }
259 }).describef(recv, "validate receiver %s", recv)
260 }
261
262 sig.params = NewTuple(params...)
263 sig.results = NewTuple(results...)
264 sig.variadic = variadic
265 }
266
267
268
269 func (check *Checker) collectParams(scope *Scope, list []*syntax.Field, variadicOk bool) (params []*Var, variadic bool) {
270 if list == nil {
271 return
272 }
273
274 var named, anonymous bool
275
276 var typ Type
277 var prev syntax.Expr
278 for i, field := range list {
279 ftype := field.Type
280
281 if ftype != prev {
282 prev = ftype
283 if t, _ := ftype.(*syntax.DotsType); t != nil {
284 ftype = t.Elem
285 if variadicOk && i == len(list)-1 {
286 variadic = true
287 } else {
288 check.softErrorf(t, "can only use ... with final parameter in list")
289
290 }
291 }
292 typ = check.varType(ftype)
293 }
294
295
296 if field.Name != nil {
297
298 name := field.Name.Value
299 if name == "" {
300 check.error(field.Name, invalidAST+"anonymous parameter")
301
302 }
303 par := NewParam(field.Name.Pos(), check.pkg, name, typ)
304 check.declare(scope, field.Name, par, scope.pos)
305 params = append(params, par)
306 named = true
307 } else {
308
309 par := NewParam(field.Pos(), check.pkg, "", typ)
310 check.recordImplicit(field, par)
311 params = append(params, par)
312 anonymous = true
313 }
314 }
315
316 if named && anonymous {
317 check.error(list[0], invalidAST+"list contains both named and anonymous parameters")
318
319 }
320
321
322
323
324 if variadic {
325 last := params[len(params)-1]
326 last.typ = &Slice{elem: last.typ}
327 check.recordTypeAndValue(list[len(list)-1].Type, typexpr, last.typ, nil)
328 }
329
330 return
331 }
332
View as plain text