Source file
src/go/types/signature.go
1
2
3
4
5 package types
6
7 import (
8 "fmt"
9 "go/ast"
10 "go/token"
11 . "internal/types/errors"
12 )
13
14
15
16
17
18
19 type Signature struct {
20
21
22
23
24 rparams *TypeParamList
25 tparams *TypeParamList
26 scope *Scope
27 recv *Var
28 params *Tuple
29 results *Tuple
30 variadic bool
31 }
32
33
34
35
36
37
38
39 func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
40 return NewSignatureType(recv, nil, nil, params, results, variadic)
41 }
42
43
44
45
46
47
48
49 func NewSignatureType(recv *Var, recvTypeParams, typeParams []*TypeParam, params, results *Tuple, variadic bool) *Signature {
50 if variadic {
51 n := params.Len()
52 if n == 0 {
53 panic("variadic function must have at least one parameter")
54 }
55 core := coreString(params.At(n - 1).typ)
56 if _, ok := core.(*Slice); !ok && !isString(core) {
57 panic(fmt.Sprintf("got %s, want variadic parameter with unnamed slice type or string as core type", core.String()))
58 }
59 }
60 sig := &Signature{recv: recv, params: params, results: results, variadic: variadic}
61 if len(recvTypeParams) != 0 {
62 if recv == nil {
63 panic("function with receiver type parameters must have a receiver")
64 }
65 sig.rparams = bindTParams(recvTypeParams)
66 }
67 if len(typeParams) != 0 {
68 if recv != nil {
69 panic("function with type parameters cannot have a receiver")
70 }
71 sig.tparams = bindTParams(typeParams)
72 }
73 return sig
74 }
75
76
77
78
79
80
81
82 func (s *Signature) Recv() *Var { return s.recv }
83
84
85 func (s *Signature) TypeParams() *TypeParamList { return s.tparams }
86
87
88 func (s *Signature) RecvTypeParams() *TypeParamList { return s.rparams }
89
90
91 func (s *Signature) Params() *Tuple { return s.params }
92
93
94 func (s *Signature) Results() *Tuple { return s.results }
95
96
97 func (s *Signature) Variadic() bool { return s.variadic }
98
99 func (s *Signature) Underlying() Type { return s }
100 func (s *Signature) String() string { return TypeString(s, nil) }
101
102
103
104
105
106 func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
107 check.openScope(ftyp, "function")
108 check.scope.isFunc = true
109 check.recordScope(ftyp, check.scope)
110 sig.scope = check.scope
111 defer check.closeScope()
112
113
114 var recv *Var
115 var rparams *TypeParamList
116 if recvPar != nil && recvPar.NumFields() > 0 {
117
118 if n := len(recvPar.List); n > 1 {
119 check.error(recvPar.List[n-1], InvalidRecv, "method has multiple receivers")
120
121 }
122
123 scopePos := ftyp.Pos()
124 recv, rparams = check.collectRecv(recvPar.List[0], scopePos)
125 }
126
127
128 if ftyp.TypeParams != nil {
129
130
131
132 if recvPar != nil {
133 check.error(ftyp.TypeParams, InvalidMethodTypeParams, "methods cannot have type parameters")
134 }
135 check.collectTypeParams(&sig.tparams, ftyp.TypeParams)
136 }
137
138
139 pnames, params, variadic := check.collectParams(ftyp.Params, true)
140 rnames, results, _ := check.collectParams(ftyp.Results, false)
141
142
143 scopePos := ftyp.End()
144 if recv != nil && recv.name != "" {
145 check.declare(check.scope, recvPar.List[0].Names[0], recv, scopePos)
146 }
147 check.declareParams(pnames, params, scopePos)
148 check.declareParams(rnames, results, scopePos)
149
150 sig.recv = recv
151 sig.rparams = rparams
152 sig.params = NewTuple(params...)
153 sig.results = NewTuple(results...)
154 sig.variadic = variadic
155 }
156
157
158
159
160 func (check *Checker) collectRecv(rparam *ast.Field, scopePos token.Pos) (recv *Var, recvTParamsList *TypeParamList) {
161
162
163
164
165
166
167 rptr, rbase, rtparams := check.unpackRecv(rparam.Type, true)
168
169
170 var recvType Type = Typ[Invalid]
171 if rtparams == nil {
172
173
174
175
176
177 recvType = check.varType(rparam.Type)
178 } else {
179
180 var baseType *Named
181 var cause string
182 if t := check.genericType(rbase, &cause); cause == "" {
183 baseType = asNamed(t)
184 } else {
185 check.errorf(rbase, InvalidRecv, "%s", cause)
186
187 }
188
189
190
191
192
193 recvTParams := make([]*TypeParam, len(rtparams))
194 for i, rparam := range rtparams {
195 tpar := check.declareTypeParam(rparam, scopePos)
196 recvTParams[i] = tpar
197
198
199
200 check.recordUse(rparam, tpar.obj)
201 check.recordTypeAndValue(rparam, typexpr, tpar, nil)
202 }
203 recvTParamsList = bindTParams(recvTParams)
204
205
206
207 if baseType != nil {
208 baseTParams := baseType.TypeParams().list()
209 if len(recvTParams) == len(baseTParams) {
210 smap := makeRenameMap(baseTParams, recvTParams)
211 for i, recvTPar := range recvTParams {
212 baseTPar := baseTParams[i]
213 check.mono.recordCanon(recvTPar, baseTPar)
214
215
216
217 recvTPar.bound = check.subst(recvTPar.obj.pos, baseTPar.bound, smap, nil, check.context())
218 }
219 } else {
220 got := measure(len(recvTParams), "type parameter")
221 check.errorf(rbase, BadRecv, "receiver declares %s, but receiver base type declares %d", got, len(baseTParams))
222 }
223
224
225
226 check.verifyVersionf(rbase, go1_18, "type instantiation")
227 targs := make([]Type, len(recvTParams))
228 for i, targ := range recvTParams {
229 targs[i] = targ
230 }
231 recvType = check.instance(rparam.Type.Pos(), baseType, targs, nil, check.context())
232 check.recordInstance(rbase, targs, recvType)
233
234
235 if rptr && isValid(recvType) {
236 recvType = NewPointer(recvType)
237 }
238
239 check.recordParenthesizedRecvTypes(rparam.Type, recvType)
240 }
241 }
242
243
244 var rname *ast.Ident
245 if n := len(rparam.Names); n >= 1 {
246 if n > 1 {
247 check.error(rparam.Names[n-1], InvalidRecv, "method has multiple receivers")
248 }
249 rname = rparam.Names[0]
250 }
251
252
253 if rname != nil && rname.Name != "" {
254
255 recv = NewParam(rname.Pos(), check.pkg, rname.Name, recvType)
256
257
258
259 } else {
260
261 recv = NewParam(rparam.Pos(), check.pkg, "", recvType)
262 check.recordImplicit(rparam, recv)
263 }
264
265
266
267 check.later(func() {
268 check.validRecv(recv, len(rtparams) != 0)
269 }).describef(recv, "validRecv(%s)", recv)
270
271 return
272 }
273
274
275
276
277
278
279
280
281
282
283
284 func (check *Checker) recordParenthesizedRecvTypes(expr ast.Expr, typ Type) {
285 for {
286 check.recordTypeAndValue(expr, typexpr, typ, nil)
287 switch e := expr.(type) {
288 case *ast.ParenExpr:
289 expr = e.X
290 case *ast.StarExpr:
291 expr = e.X
292
293
294 ptr, _ := typ.(*Pointer)
295 if ptr == nil {
296 return
297 }
298 typ = ptr.base
299 default:
300 return
301 }
302 }
303 }
304
305
306
307
308 func (check *Checker) collectParams(list *ast.FieldList, variadicOk bool) (names []*ast.Ident, params []*Var, variadic bool) {
309 if list == nil {
310 return
311 }
312
313 var named, anonymous bool
314 for i, field := range list.List {
315 ftype := field.Type
316 if t, _ := ftype.(*ast.Ellipsis); t != nil {
317 ftype = t.Elt
318 if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
319 variadic = true
320 } else {
321 check.softErrorf(t, MisplacedDotDotDot, "can only use ... with final parameter in list")
322
323 }
324 }
325 typ := check.varType(ftype)
326
327
328 if len(field.Names) > 0 {
329
330 for _, name := range field.Names {
331 if name.Name == "" {
332 check.error(name, InvalidSyntaxTree, "anonymous parameter")
333
334 }
335 par := NewParam(name.Pos(), check.pkg, name.Name, typ)
336
337 names = append(names, name)
338 params = append(params, par)
339 }
340 named = true
341 } else {
342
343 par := NewParam(ftype.Pos(), check.pkg, "", typ)
344 check.recordImplicit(field, par)
345 names = append(names, nil)
346 params = append(params, par)
347 anonymous = true
348 }
349 }
350
351 if named && anonymous {
352 check.error(list, InvalidSyntaxTree, "list contains both named and anonymous parameters")
353
354 }
355
356
357
358
359 if variadic {
360 last := params[len(params)-1]
361 last.typ = &Slice{elem: last.typ}
362 check.recordTypeAndValue(list.List[len(list.List)-1].Type, typexpr, last.typ, nil)
363 }
364
365 return
366 }
367
368
369 func (check *Checker) declareParams(names []*ast.Ident, params []*Var, scopePos token.Pos) {
370 for i, name := range names {
371 if name != nil && name.Name != "" {
372 check.declare(check.scope, name, params[i], scopePos)
373 }
374 }
375 }
376
377
378
379
380 func (check *Checker) validRecv(recv *Var, hasTypeParams bool) {
381
382 rtyp, _ := deref(recv.typ)
383 atyp := Unalias(rtyp)
384 if !isValid(atyp) {
385 return
386 }
387
388
389
390 switch T := atyp.(type) {
391 case *Named:
392
393
394
395
396 if T.TypeArgs() != nil && !hasTypeParams {
397 check.errorf(recv, InvalidRecv, "cannot define new methods on instantiated type %s", rtyp)
398 break
399 }
400 if T.obj.pkg != check.pkg {
401 check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
402 break
403 }
404 var cause string
405 switch u := T.under().(type) {
406 case *Basic:
407
408 if u.kind == UnsafePointer {
409 cause = "unsafe.Pointer"
410 }
411 case *Pointer, *Interface:
412 cause = "pointer or interface type"
413 case *TypeParam:
414
415
416 panic("unreachable")
417 }
418 if cause != "" {
419 check.errorf(recv, InvalidRecv, "invalid receiver type %s (%s)", rtyp, cause)
420 }
421 case *Basic:
422 check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
423 default:
424 check.errorf(recv, InvalidRecv, "invalid receiver type %s", recv.typ)
425 }
426 }
427
View as plain text