1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 // This file implements typechecking of call and selector expressions.
6 7 package types
8 9 import (
10 "go/ast"
11 "go/token"
12 . "internal/types/errors"
13 "strings"
14 )
15 16 // funcInst type-checks a function instantiation.
17 // The incoming x must be a generic function.
18 // If ix != nil, it provides some or all of the type arguments (ix.Indices).
19 // If target != nil, it may be used to infer missing type arguments of x, if any.
20 // At least one of T or ix must be provided.
21 //
22 // There are two modes of operation:
23 //
24 // 1. If infer == true, funcInst infers missing type arguments as needed and
25 // instantiates the function x. The returned results are nil.
26 //
27 // 2. If infer == false and inst provides all type arguments, funcInst
28 // instantiates the function x. The returned results are nil.
29 // If inst doesn't provide enough type arguments, funcInst returns the
30 // available arguments; x remains unchanged.
31 //
32 // If an error (other than a version error) occurs in any case, it is reported
33 // and x.mode is set to invalid.
34 func (check *Checker) funcInst(T *target, pos token.Pos, x *operand, ix *indexedExpr, infer bool) []Type {
35 assert(T != nil || ix != nil)
36 37 var instErrPos positioner
38 if ix != nil {
39 instErrPos = inNode(ix.orig, ix.lbrack)
40 x.expr = ix.orig // if we don't have an index expression, keep the existing expression of x
41 } else {
42 instErrPos = atPos(pos)
43 }
44 versionErr := !check.verifyVersionf(instErrPos, go1_18, "function instantiation")
45 46 // targs and xlist are the type arguments and corresponding type expressions, or nil.
47 var targs []Type
48 var xlist []ast.Expr
49 if ix != nil {
50 xlist = ix.indices
51 targs = check.typeList(xlist)
52 if targs == nil {
53 x.mode = invalid
54 return nil
55 }
56 assert(len(targs) == len(xlist))
57 }
58 59 // Check the number of type arguments (got) vs number of type parameters (want).
60 // Note that x is a function value, not a type expression, so we don't need to
61 // call under below.
62 sig := x.typ.(*Signature)
63 got, want := len(targs), sig.TypeParams().Len()
64 if got > want {
65 // Providing too many type arguments is always an error.
66 check.errorf(ix.indices[got-1], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
67 x.mode = invalid
68 return nil
69 }
70 71 if got < want {
72 if !infer {
73 return targs
74 }
75 76 // If the uninstantiated or partially instantiated function x is used in
77 // an assignment (tsig != nil), infer missing type arguments by treating
78 // the assignment
79 //
80 // var tvar tsig = x
81 //
82 // like a call g(tvar) of the synthetic generic function g
83 //
84 // func g[type_parameters_of_x](func_type_of_x)
85 //
86 var args []*operand
87 var params []*Var
88 var reverse bool
89 if T != nil && sig.tparams != nil {
90 if !versionErr && !check.allowVersion(go1_21) {
91 if ix != nil {
92 check.versionErrorf(instErrPos, go1_21, "partially instantiated function in assignment")
93 } else {
94 check.versionErrorf(instErrPos, go1_21, "implicitly instantiated function in assignment")
95 }
96 }
97 gsig := NewSignatureType(nil, nil, nil, sig.params, sig.results, sig.variadic)
98 params = []*Var{NewParam(x.Pos(), check.pkg, "", gsig)}
99 // The type of the argument operand is tsig, which is the type of the LHS in an assignment
100 // or the result type in a return statement. Create a pseudo-expression for that operand
101 // that makes sense when reported in error messages from infer, below.
102 expr := ast.NewIdent(T.desc)
103 expr.NamePos = x.Pos() // correct position
104 args = []*operand{{mode: value, expr: expr, typ: T.sig}}
105 reverse = true
106 }
107 108 // Rename type parameters to avoid problems with recursive instantiations.
109 // Note that NewTuple(params...) below is (*Tuple)(nil) if len(params) == 0, as desired.
110 tparams, params2 := check.renameTParams(pos, sig.TypeParams().list(), NewTuple(params...))
111 112 err := check.newError(CannotInferTypeArgs)
113 targs = check.infer(atPos(pos), tparams, targs, params2.(*Tuple), args, reverse, err)
114 if targs == nil {
115 if !err.empty() {
116 err.report()
117 }
118 x.mode = invalid
119 return nil
120 }
121 got = len(targs)
122 }
123 assert(got == want)
124 125 // instantiate function signature
126 sig = check.instantiateSignature(x.Pos(), x.expr, sig, targs, xlist)
127 x.typ = sig
128 x.mode = value
129 return nil
130 }
131 132 func (check *Checker) instantiateSignature(pos token.Pos, expr ast.Expr, typ *Signature, targs []Type, xlist []ast.Expr) (res *Signature) {
133 assert(check != nil)
134 assert(len(targs) == typ.TypeParams().Len())
135 136 if check.conf._Trace {
137 check.trace(pos, "-- instantiating signature %s with %s", typ, targs)
138 check.indent++
139 defer func() {
140 check.indent--
141 check.trace(pos, "=> %s (under = %s)", res, res.Underlying())
142 }()
143 }
144 145 // For signatures, Checker.instance will always succeed because the type argument
146 // count is correct at this point (see assertion above); hence the type assertion
147 // to *Signature will always succeed.
148 inst := check.instance(pos, typ, targs, nil, check.context()).(*Signature)
149 assert(inst.TypeParams().Len() == 0) // signature is not generic anymore
150 check.recordInstance(expr, targs, inst)
151 assert(len(xlist) <= len(targs))
152 153 // verify instantiation lazily (was go.dev/issue/50450)
154 check.later(func() {
155 tparams := typ.TypeParams().list()
156 // check type constraints
157 if i, err := check.verify(pos, tparams, targs, check.context()); err != nil {
158 // best position for error reporting
159 pos := pos
160 if i < len(xlist) {
161 pos = xlist[i].Pos()
162 }
163 check.softErrorf(atPos(pos), InvalidTypeArg, "%s", err)
164 } else {
165 check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
166 }
167 }).describef(atPos(pos), "verify instantiation")
168 169 return inst
170 }
171 172 func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
173 ix := unpackIndexedExpr(call.Fun)
174 if ix != nil {
175 if check.indexExpr(x, ix) {
176 // Delay function instantiation to argument checking,
177 // where we combine type and value arguments for type
178 // inference.
179 assert(x.mode == value)
180 } else {
181 ix = nil
182 }
183 x.expr = call.Fun
184 check.record(x)
185 } else {
186 check.exprOrType(x, call.Fun, true)
187 }
188 // x.typ may be generic
189 190 switch x.mode {
191 case invalid:
192 check.use(call.Args...)
193 x.expr = call
194 return statement
195 196 case typexpr:
197 // conversion
198 check.nonGeneric(nil, x)
199 if x.mode == invalid {
200 return conversion
201 }
202 T := x.typ
203 x.mode = invalid
204 switch n := len(call.Args); n {
205 case 0:
206 check.errorf(inNode(call, call.Rparen), WrongArgCount, "missing argument in conversion to %s", T)
207 case 1:
208 check.expr(nil, x, call.Args[0])
209 if x.mode != invalid {
210 if hasDots(call) {
211 check.errorf(call.Args[0], BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
212 break
213 }
214 if t, _ := under(T).(*Interface); t != nil && !isTypeParam(T) {
215 if !t.IsMethodSet() {
216 check.errorf(call, MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
217 break
218 }
219 }
220 check.conversion(x, T)
221 }
222 default:
223 check.use(call.Args...)
224 check.errorf(call.Args[n-1], WrongArgCount, "too many arguments in conversion to %s", T)
225 }
226 x.expr = call
227 return conversion
228 229 case builtin:
230 // no need to check for non-genericity here
231 id := x.id
232 if !check.builtin(x, call, id) {
233 x.mode = invalid
234 }
235 x.expr = call
236 // a non-constant result implies a function call
237 if x.mode != invalid && x.mode != constant_ {
238 check.hasCallOrRecv = true
239 }
240 return predeclaredFuncs[id].kind
241 }
242 243 // ordinary function/method call
244 // signature may be generic
245 cgocall := x.mode == cgofunc
246 247 // If the operand type is a type parameter, all types in its type set
248 // must have a common underlying type, which must be a signature.
249 u, err := commonUnder(x.typ, func(t, u Type) *typeError {
250 if _, ok := u.(*Signature); u != nil && !ok {
251 return typeErrorf("%s is not a function", t)
252 }
253 return nil
254 })
255 if err != nil {
256 check.errorf(x, InvalidCall, invalidOp+"cannot call %s: %s", x, err.format(check))
257 x.mode = invalid
258 x.expr = call
259 return statement
260 }
261 sig := u.(*Signature) // u must be a signature per the commonUnder condition
262 263 // Capture wasGeneric before sig is potentially instantiated below.
264 wasGeneric := sig.TypeParams().Len() > 0
265 266 // evaluate type arguments, if any
267 var xlist []ast.Expr
268 var targs []Type
269 if ix != nil {
270 xlist = ix.indices
271 targs = check.typeList(xlist)
272 if targs == nil {
273 check.use(call.Args...)
274 x.mode = invalid
275 x.expr = call
276 return statement
277 }
278 assert(len(targs) == len(xlist))
279 280 // check number of type arguments (got) vs number of type parameters (want)
281 got, want := len(targs), sig.TypeParams().Len()
282 if got > want {
283 check.errorf(xlist[want], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
284 check.use(call.Args...)
285 x.mode = invalid
286 x.expr = call
287 return statement
288 }
289 290 // If sig is generic and all type arguments are provided, preempt function
291 // argument type inference by explicitly instantiating the signature. This
292 // ensures that we record accurate type information for sig, even if there
293 // is an error checking its arguments (for example, if an incorrect number
294 // of arguments is supplied).
295 if got == want && want > 0 {
296 check.verifyVersionf(atPos(ix.lbrack), go1_18, "function instantiation")
297 sig = check.instantiateSignature(ix.Pos(), ix.orig, sig, targs, xlist)
298 // targs have been consumed; proceed with checking arguments of the
299 // non-generic signature.
300 targs = nil
301 xlist = nil
302 }
303 }
304 305 // evaluate arguments
306 args, atargs := check.genericExprList(call.Args)
307 sig = check.arguments(call, sig, targs, xlist, args, atargs)
308 309 if wasGeneric && sig.TypeParams().Len() == 0 {
310 // Update the recorded type of call.Fun to its instantiated type.
311 check.recordTypeAndValue(call.Fun, value, sig, nil)
312 }
313 314 // determine result
315 switch sig.results.Len() {
316 case 0:
317 x.mode = novalue
318 case 1:
319 if cgocall {
320 x.mode = commaerr
321 } else {
322 x.mode = value
323 }
324 x.typ = sig.results.vars[0].typ // unpack tuple
325 default:
326 x.mode = value
327 x.typ = sig.results
328 }
329 x.expr = call
330 check.hasCallOrRecv = true
331 332 // if type inference failed, a parameterized result must be invalidated
333 // (operands cannot have a parameterized type)
334 if x.mode == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ) {
335 x.mode = invalid
336 }
337 338 return statement
339 }
340 341 // exprList evaluates a list of expressions and returns the corresponding operands.
342 // A single-element expression list may evaluate to multiple operands.
343 func (check *Checker) exprList(elist []ast.Expr) (xlist []*operand) {
344 if n := len(elist); n == 1 {
345 xlist, _ = check.multiExpr(elist[0], false)
346 } else if n > 1 {
347 // multiple (possibly invalid) values
348 xlist = make([]*operand, n)
349 for i, e := range elist {
350 var x operand
351 check.expr(nil, &x, e)
352 xlist[i] = &x
353 }
354 }
355 return
356 }
357 358 // genericExprList is like exprList but result operands may be uninstantiated or partially
359 // instantiated generic functions (where constraint information is insufficient to infer
360 // the missing type arguments) for Go 1.21 and later.
361 // For each non-generic or uninstantiated generic operand, the corresponding targsList and
362 // elements do not exist (targsList is nil) or the elements are nil.
363 // For each partially instantiated generic function operand, the corresponding
364 // targsList elements are the operand's partial type arguments.
365 func (check *Checker) genericExprList(elist []ast.Expr) (resList []*operand, targsList [][]Type) {
366 if debug {
367 defer func() {
368 // type arguments must only exist for partially instantiated functions
369 for i, x := range resList {
370 if i < len(targsList) {
371 if n := len(targsList[i]); n > 0 {
372 // x must be a partially instantiated function
373 assert(n < x.typ.(*Signature).TypeParams().Len())
374 }
375 }
376 }
377 }()
378 }
379 380 // Before Go 1.21, uninstantiated or partially instantiated argument functions are
381 // nor permitted. Checker.funcInst must infer missing type arguments in that case.
382 infer := true // for -lang < go1.21
383 n := len(elist)
384 if n > 0 && check.allowVersion(go1_21) {
385 infer = false
386 }
387 388 if n == 1 {
389 // single value (possibly a partially instantiated function), or a multi-valued expression
390 e := elist[0]
391 var x operand
392 if ix := unpackIndexedExpr(e); ix != nil && check.indexExpr(&x, ix) {
393 // x is a generic function.
394 targs := check.funcInst(nil, x.Pos(), &x, ix, infer)
395 if targs != nil {
396 // x was not instantiated: collect the (partial) type arguments.
397 targsList = [][]Type{targs}
398 // Update x.expr so that we can record the partially instantiated function.
399 x.expr = ix.orig
400 } else {
401 // x was instantiated: we must record it here because we didn't
402 // use the usual expression evaluators.
403 check.record(&x)
404 }
405 resList = []*operand{&x}
406 } else {
407 // x is not a function instantiation (it may still be a generic function).
408 check.rawExpr(nil, &x, e, nil, true)
409 check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
410 if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
411 // x is a function call returning multiple values; it cannot be generic.
412 resList = make([]*operand, t.Len())
413 for i, v := range t.vars {
414 resList[i] = &operand{mode: value, expr: e, typ: v.typ}
415 }
416 } else {
417 // x is exactly one value (possibly invalid or uninstantiated generic function).
418 resList = []*operand{&x}
419 }
420 }
421 } else if n > 1 {
422 // multiple values
423 resList = make([]*operand, n)
424 targsList = make([][]Type, n)
425 for i, e := range elist {
426 var x operand
427 if ix := unpackIndexedExpr(e); ix != nil && check.indexExpr(&x, ix) {
428 // x is a generic function.
429 targs := check.funcInst(nil, x.Pos(), &x, ix, infer)
430 if targs != nil {
431 // x was not instantiated: collect the (partial) type arguments.
432 targsList[i] = targs
433 // Update x.expr so that we can record the partially instantiated function.
434 x.expr = ix.orig
435 } else {
436 // x was instantiated: we must record it here because we didn't
437 // use the usual expression evaluators.
438 check.record(&x)
439 }
440 } else {
441 // x is exactly one value (possibly invalid or uninstantiated generic function).
442 check.genericExpr(&x, e)
443 }
444 resList[i] = &x
445 }
446 }
447 448 return
449 }
450 451 // arguments type-checks arguments passed to a function call with the given signature.
452 // The function and its arguments may be generic, and possibly partially instantiated.
453 // targs and xlist are the function's type arguments (and corresponding expressions).
454 // args are the function arguments. If an argument args[i] is a partially instantiated
455 // generic function, atargs[i] are the corresponding type arguments.
456 // If the callee is variadic, arguments adjusts its signature to match the provided
457 // arguments. The type parameters and arguments of the callee and all its arguments
458 // are used together to infer any missing type arguments, and the callee and argument
459 // functions are instantiated as necessary.
460 // The result signature is the (possibly adjusted and instantiated) function signature.
461 // If an error occurred, the result signature is the incoming sig.
462 func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type, xlist []ast.Expr, args []*operand, atargs [][]Type) (rsig *Signature) {
463 rsig = sig
464 465 // Function call argument/parameter count requirements
466 //
467 // | standard call | dotdotdot call |
468 // --------------+------------------+----------------+
469 // standard func | nargs == npars | invalid |
470 // --------------+------------------+----------------+
471 // variadic func | nargs >= npars-1 | nargs == npars |
472 // --------------+------------------+----------------+
473 474 nargs := len(args)
475 npars := sig.params.Len()
476 ddd := hasDots(call)
477 478 // set up parameters
479 sigParams := sig.params // adjusted for variadic functions (may be nil for empty parameter lists!)
480 adjusted := false // indicates if sigParams is different from sig.params
481 if sig.variadic {
482 if ddd {
483 // variadic_func(a, b, c...)
484 if len(call.Args) == 1 && nargs > 1 {
485 // f()... is not permitted if f() is multi-valued
486 check.errorf(inNode(call, call.Ellipsis), InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.Args[0])
487 return
488 }
489 } else {
490 // variadic_func(a, b, c)
491 if nargs >= npars-1 {
492 // Create custom parameters for arguments: keep
493 // the first npars-1 parameters and add one for
494 // each argument mapping to the ... parameter.
495 vars := make([]*Var, npars-1) // npars > 0 for variadic functions
496 copy(vars, sig.params.vars)
497 last := sig.params.vars[npars-1]
498 typ := last.typ.(*Slice).elem
499 for len(vars) < nargs {
500 vars = append(vars, NewParam(last.pos, last.pkg, last.name, typ))
501 }
502 sigParams = NewTuple(vars...) // possibly nil!
503 adjusted = true
504 npars = nargs
505 } else {
506 // nargs < npars-1
507 npars-- // for correct error message below
508 }
509 }
510 } else {
511 if ddd {
512 // standard_func(a, b, c...)
513 check.errorf(inNode(call, call.Ellipsis), NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
514 return
515 }
516 // standard_func(a, b, c)
517 }
518 519 // check argument count
520 if nargs != npars {
521 var at positioner = call
522 qualifier := "not enough"
523 if nargs > npars {
524 at = args[npars].expr // report at first extra argument
525 qualifier = "too many"
526 } else {
527 at = atPos(call.Rparen) // report at closing )
528 }
529 // take care of empty parameter lists represented by nil tuples
530 var params []*Var
531 if sig.params != nil {
532 params = sig.params.vars
533 }
534 err := check.newError(WrongArgCount)
535 err.addf(at, "%s arguments in call to %s", qualifier, call.Fun)
536 err.addf(noposn, "have %s", check.typesSummary(operandTypes(args), false, ddd))
537 err.addf(noposn, "want %s", check.typesSummary(varTypes(params), sig.variadic, false))
538 err.report()
539 return
540 }
541 542 // collect type parameters of callee and generic function arguments
543 var tparams []*TypeParam
544 545 // collect type parameters of callee
546 n := sig.TypeParams().Len()
547 if n > 0 {
548 if !check.allowVersion(go1_18) {
549 switch call.Fun.(type) {
550 case *ast.IndexExpr, *ast.IndexListExpr:
551 ix := unpackIndexedExpr(call.Fun)
552 check.versionErrorf(inNode(call.Fun, ix.lbrack), go1_18, "function instantiation")
553 default:
554 check.versionErrorf(inNode(call, call.Lparen), go1_18, "implicit function instantiation")
555 }
556 }
557 // rename type parameters to avoid problems with recursive calls
558 var tmp Type
559 tparams, tmp = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams)
560 sigParams = tmp.(*Tuple)
561 // make sure targs and tparams have the same length
562 for len(targs) < len(tparams) {
563 targs = append(targs, nil)
564 }
565 }
566 assert(len(tparams) == len(targs))
567 568 // collect type parameters from generic function arguments
569 var genericArgs []int // indices of generic function arguments
570 if enableReverseTypeInference {
571 for i, arg := range args {
572 // generic arguments cannot have a defined (*Named) type - no need for underlying type below
573 if asig, _ := arg.typ.(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
574 // The argument type is a generic function signature. This type is
575 // pointer-identical with (it's copied from) the type of the generic
576 // function argument and thus the function object.
577 // Before we change the type (type parameter renaming, below), make
578 // a clone of it as otherwise we implicitly modify the object's type
579 // (go.dev/issues/63260).
580 asig = clone(asig)
581 // Rename type parameters for cases like f(g, g); this gives each
582 // generic function argument a unique type identity (go.dev/issues/59956).
583 // TODO(gri) Consider only doing this if a function argument appears
584 // multiple times, which is rare (possible optimization).
585 atparams, tmp := check.renameTParams(call.Pos(), asig.TypeParams().list(), asig)
586 asig = tmp.(*Signature)
587 asig.tparams = &TypeParamList{atparams} // renameTParams doesn't touch associated type parameters
588 arg.typ = asig // new type identity for the function argument
589 tparams = append(tparams, atparams...)
590 // add partial list of type arguments, if any
591 if i < len(atargs) {
592 targs = append(targs, atargs[i]...)
593 }
594 // make sure targs and tparams have the same length
595 for len(targs) < len(tparams) {
596 targs = append(targs, nil)
597 }
598 genericArgs = append(genericArgs, i)
599 }
600 }
601 }
602 assert(len(tparams) == len(targs))
603 604 // at the moment we only support implicit instantiations of argument functions
605 _ = len(genericArgs) > 0 && check.verifyVersionf(args[genericArgs[0]], go1_21, "implicitly instantiated function as argument")
606 607 // tparams holds the type parameters of the callee and generic function arguments, if any:
608 // the first n type parameters belong to the callee, followed by mi type parameters for each
609 // of the generic function arguments, where mi = args[i].typ.(*Signature).TypeParams().Len().
610 611 // infer missing type arguments of callee and function arguments
612 if len(tparams) > 0 {
613 err := check.newError(CannotInferTypeArgs)
614 targs = check.infer(call, tparams, targs, sigParams, args, false, err)
615 if targs == nil {
616 // TODO(gri) If infer inferred the first targs[:n], consider instantiating
617 // the call signature for better error messages/gopls behavior.
618 // Perhaps instantiate as much as we can, also for arguments.
619 // This will require changes to how infer returns its results.
620 if !err.empty() {
621 check.errorf(err.posn(), CannotInferTypeArgs, "in call to %s, %s", call.Fun, err.msg())
622 }
623 return
624 }
625 626 // update result signature: instantiate if needed
627 if n > 0 {
628 rsig = check.instantiateSignature(call.Pos(), call.Fun, sig, targs[:n], xlist)
629 // If the callee's parameter list was adjusted we need to update (instantiate)
630 // it separately. Otherwise we can simply use the result signature's parameter
631 // list.
632 if adjusted {
633 sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
634 } else {
635 sigParams = rsig.params
636 }
637 }
638 639 // compute argument signatures: instantiate if needed
640 j := n
641 for _, i := range genericArgs {
642 arg := args[i]
643 asig := arg.typ.(*Signature)
644 k := j + asig.TypeParams().Len()
645 // targs[j:k] are the inferred type arguments for asig
646 arg.typ = check.instantiateSignature(call.Pos(), arg.expr, asig, targs[j:k], nil) // TODO(gri) provide xlist if possible (partial instantiations)
647 check.record(arg) // record here because we didn't use the usual expr evaluators
648 j = k
649 }
650 }
651 652 // check arguments
653 if len(args) > 0 {
654 context := check.sprintf("argument to %s", call.Fun)
655 for i, a := range args {
656 check.assignment(a, sigParams.vars[i].typ, context)
657 }
658 }
659 660 return
661 }
662 663 var cgoPrefixes = [...]string{
664 "_Ciconst_",
665 "_Cfconst_",
666 "_Csconst_",
667 "_Ctype_",
668 "_Cvar_", // actually a pointer to the var
669 "_Cfpvar_fp_",
670 "_Cfunc_",
671 "_Cmacro_", // function to evaluate the expanded expression
672 }
673 674 func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *TypeName, wantType bool) {
675 // these must be declared before the "goto Error" statements
676 var (
677 obj Object
678 index []int
679 indirect bool
680 )
681 682 sel := e.Sel.Name
683 // If the identifier refers to a package, handle everything here
684 // so we don't need a "package" mode for operands: package names
685 // can only appear in qualified identifiers which are mapped to
686 // selector expressions.
687 if ident, ok := e.X.(*ast.Ident); ok {
688 obj := check.lookup(ident.Name)
689 if pname, _ := obj.(*PkgName); pname != nil {
690 assert(pname.pkg == check.pkg)
691 check.recordUse(ident, pname)
692 check.usedPkgNames[pname] = true
693 pkg := pname.imported
694 695 var exp Object
696 funcMode := value
697 if pkg.cgo {
698 // cgo special cases C.malloc: it's
699 // rewritten to _CMalloc and does not
700 // support two-result calls.
701 if sel == "malloc" {
702 sel = "_CMalloc"
703 } else {
704 funcMode = cgofunc
705 }
706 for _, prefix := range cgoPrefixes {
707 // cgo objects are part of the current package (in file
708 // _cgo_gotypes.go). Use regular lookup.
709 exp = check.lookup(prefix + sel)
710 if exp != nil {
711 break
712 }
713 }
714 if exp == nil {
715 if isValidName(sel) {
716 check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e)) // cast to ast.Expr to silence vet
717 }
718 goto Error
719 }
720 check.objDecl(exp, nil)
721 } else {
722 exp = pkg.scope.Lookup(sel)
723 if exp == nil {
724 if !pkg.fake && isValidName(sel) {
725 // Try to give a better error message when selector matches an object name ignoring case.
726 exps := pkg.scope.lookupIgnoringCase(sel, true)
727 if len(exps) >= 1 {
728 // report just the first one
729 check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s (but have %s)", ast.Expr(e), exps[0].Name())
730 } else {
731 check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e))
732 }
733 }
734 goto Error
735 }
736 if !exp.Exported() {
737 check.errorf(e.Sel, UnexportedName, "name %s not exported by package %s", sel, pkg.name)
738 // ok to continue
739 }
740 }
741 check.recordUse(e.Sel, exp)
742 743 // Simplified version of the code for *ast.Idents:
744 // - imported objects are always fully initialized
745 switch exp := exp.(type) {
746 case *Const:
747 assert(exp.Val() != nil)
748 x.mode = constant_
749 x.typ = exp.typ
750 x.val = exp.val
751 case *TypeName:
752 x.mode = typexpr
753 x.typ = exp.typ
754 case *Var:
755 x.mode = variable
756 x.typ = exp.typ
757 if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
758 x.typ = x.typ.(*Pointer).base
759 }
760 case *Func:
761 x.mode = funcMode
762 x.typ = exp.typ
763 if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
764 x.mode = value
765 x.typ = x.typ.(*Signature).results.vars[0].typ
766 }
767 case *Builtin:
768 x.mode = builtin
769 x.typ = exp.typ
770 x.id = exp.id
771 default:
772 check.dump("%v: unexpected object %v", e.Sel.Pos(), exp)
773 panic("unreachable")
774 }
775 x.expr = e
776 return
777 }
778 }
779 780 check.exprOrType(x, e.X, false)
781 switch x.mode {
782 case typexpr:
783 // don't crash for "type T T.x" (was go.dev/issue/51509)
784 if def != nil && def.typ == x.typ {
785 check.cycleError([]Object{def}, 0)
786 goto Error
787 }
788 case builtin:
789 // types2 uses the position of '.' for the error
790 check.errorf(e.Sel, UncalledBuiltin, "invalid use of %s in selector expression", x)
791 goto Error
792 case invalid:
793 goto Error
794 }
795 796 // Avoid crashing when checking an invalid selector in a method declaration
797 // (i.e., where def is not set):
798 //
799 // type S[T any] struct{}
800 // type V = S[any]
801 // func (fs *S[T]) M(x V.M) {}
802 //
803 // All codepaths below return a non-type expression. If we get here while
804 // expecting a type expression, it is an error.
805 //
806 // See go.dev/issue/57522 for more details.
807 //
808 // TODO(rfindley): We should do better by refusing to check selectors in all cases where
809 // x.typ is incomplete.
810 if wantType {
811 check.errorf(e.Sel, NotAType, "%s is not a type", ast.Expr(e))
812 goto Error
813 }
814 815 obj, index, indirect = lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel, false)
816 if obj == nil {
817 // Don't report another error if the underlying type was invalid (go.dev/issue/49541).
818 if !isValid(under(x.typ)) {
819 goto Error
820 }
821 822 if index != nil {
823 // TODO(gri) should provide actual type where the conflict happens
824 check.errorf(e.Sel, AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
825 goto Error
826 }
827 828 if indirect {
829 if x.mode == typexpr {
830 check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel)
831 } else {
832 check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
833 }
834 goto Error
835 }
836 837 var why string
838 if isInterfacePtr(x.typ) {
839 why = check.interfacePtrError(x.typ)
840 } else {
841 alt, _, _ := lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel, true)
842 why = check.lookupError(x.typ, sel, alt, false)
843 }
844 check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
845 goto Error
846 }
847 848 // methods may not have a fully set up signature yet
849 if m, _ := obj.(*Func); m != nil {
850 check.objDecl(m, nil)
851 }
852 853 if x.mode == typexpr {
854 // method expression
855 m, _ := obj.(*Func)
856 if m == nil {
857 check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
858 goto Error
859 }
860 861 check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
862 863 sig := m.typ.(*Signature)
864 if sig.recv == nil {
865 check.error(e, InvalidDeclCycle, "illegal cycle in method declaration")
866 goto Error
867 }
868 869 // the receiver type becomes the type of the first function
870 // argument of the method expression's function type
871 var params []*Var
872 if sig.params != nil {
873 params = sig.params.vars
874 }
875 // Be consistent about named/unnamed parameters. This is not needed
876 // for type-checking, but the newly constructed signature may appear
877 // in an error message and then have mixed named/unnamed parameters.
878 // (An alternative would be to not print parameter names in errors,
879 // but it's useful to see them; this is cheap and method expressions
880 // are rare.)
881 name := ""
882 if len(params) > 0 && params[0].name != "" {
883 // name needed
884 name = sig.recv.name
885 if name == "" {
886 name = "_"
887 }
888 }
889 params = append([]*Var{NewParam(sig.recv.pos, sig.recv.pkg, name, x.typ)}, params...)
890 x.mode = value
891 x.typ = &Signature{
892 tparams: sig.tparams,
893 params: NewTuple(params...),
894 results: sig.results,
895 variadic: sig.variadic,
896 }
897 898 check.addDeclDep(m)
899 900 } else {
901 // regular selector
902 switch obj := obj.(type) {
903 case *Var:
904 check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
905 if x.mode == variable || indirect {
906 x.mode = variable
907 } else {
908 x.mode = value
909 }
910 x.typ = obj.typ
911 912 case *Func:
913 // TODO(gri) If we needed to take into account the receiver's
914 // addressability, should we report the type &(x.typ) instead?
915 check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
916 917 // TODO(gri) The verification pass below is disabled for now because
918 // method sets don't match method lookup in some cases.
919 // For instance, if we made a copy above when creating a
920 // custom method for a parameterized received type, the
921 // method set method doesn't match (no copy there). There
922 /// may be other situations.
923 disabled := true
924 if !disabled && debug {
925 // Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
926 // TODO(gri) This only works because we call LookupFieldOrMethod
927 // _before_ calling NewMethodSet: LookupFieldOrMethod completes
928 // any incomplete interfaces so they are available to NewMethodSet
929 // (which assumes that interfaces have been completed already).
930 typ := x.typ
931 if x.mode == variable {
932 // If typ is not an (unnamed) pointer or an interface,
933 // use *typ instead, because the method set of *typ
934 // includes the methods of typ.
935 // Variables are addressable, so we can always take their
936 // address.
937 if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
938 typ = &Pointer{base: typ}
939 }
940 }
941 // If we created a synthetic pointer type above, we will throw
942 // away the method set computed here after use.
943 // TODO(gri) Method set computation should probably always compute
944 // both, the value and the pointer receiver method set and represent
945 // them in a single structure.
946 // TODO(gri) Consider also using a method set cache for the lifetime
947 // of checker once we rely on MethodSet lookup instead of individual
948 // lookup.
949 mset := NewMethodSet(typ)
950 if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
951 check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
952 check.dump("%s\n", mset)
953 // Caution: MethodSets are supposed to be used externally
954 // only (after all interface types were completed). It's
955 // now possible that we get here incorrectly. Not urgent
956 // to fix since we only run this code in debug mode.
957 // TODO(gri) fix this eventually.
958 panic("method sets and lookup don't agree")
959 }
960 }
961 962 x.mode = value
963 964 // remove receiver
965 sig := *obj.typ.(*Signature)
966 sig.recv = nil
967 x.typ = &sig
968 969 check.addDeclDep(obj)
970 971 default:
972 panic("unreachable")
973 }
974 }
975 976 // everything went well
977 x.expr = e
978 return
979 980 Error:
981 x.mode = invalid
982 x.expr = e
983 }
984 985 // use type-checks each argument.
986 // Useful to make sure expressions are evaluated
987 // (and variables are "used") in the presence of
988 // other errors. Arguments may be nil.
989 // Reports if all arguments evaluated without error.
990 func (check *Checker) use(args ...ast.Expr) bool { return check.useN(args, false) }
991 992 // useLHS is like use, but doesn't "use" top-level identifiers.
993 // It should be called instead of use if the arguments are
994 // expressions on the lhs of an assignment.
995 func (check *Checker) useLHS(args ...ast.Expr) bool { return check.useN(args, true) }
996 997 func (check *Checker) useN(args []ast.Expr, lhs bool) bool {
998 ok := true
999 for _, e := range args {
1000 if !check.use1(e, lhs) {
1001 ok = false
1002 }
1003 }
1004 return ok
1005 }
1006 1007 func (check *Checker) use1(e ast.Expr, lhs bool) bool {
1008 var x operand
1009 x.mode = value // anything but invalid
1010 switch n := ast.Unparen(e).(type) {
1011 case nil:
1012 // nothing to do
1013 case *ast.Ident:
1014 // don't report an error evaluating blank
1015 if n.Name == "_" {
1016 break
1017 }
1018 // If the lhs is an identifier denoting a variable v, this assignment
1019 // is not a 'use' of v. Remember current value of v.used and restore
1020 // after evaluating the lhs via check.rawExpr.
1021 var v *Var
1022 var v_used bool
1023 if lhs {
1024 if obj := check.lookup(n.Name); obj != nil {
1025 // It's ok to mark non-local variables, but ignore variables
1026 // from other packages to avoid potential race conditions with
1027 // dot-imported variables.
1028 if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
1029 v = w
1030 v_used = check.usedVars[v]
1031 }
1032 }
1033 }
1034 check.exprOrType(&x, n, true)
1035 if v != nil {
1036 check.usedVars[v] = v_used // restore v.used
1037 }
1038 default:
1039 check.rawExpr(nil, &x, e, nil, true)
1040 }
1041 return x.mode != invalid
1042 }
1043