Source file
src/go/types/call.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "go/ast"
11 "go/token"
12 . "internal/types/errors"
13 "strings"
14 )
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
41 } else {
42 instErrPos = atPos(pos)
43 }
44 versionErr := !check.verifyVersionf(instErrPos, go1_18, "function instantiation")
45
46
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
60
61
62 sig := x.typ.(*Signature)
63 got, want := len(targs), sig.TypeParams().Len()
64 if got > want {
65
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
77
78
79
80
81
82
83
84
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
100
101
102 expr := ast.NewIdent(T.desc)
103 expr.NamePos = x.Pos()
104 args = []*operand{{mode: value, expr: expr, typ: T.sig}}
105 reverse = true
106 }
107
108
109
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
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
146
147
148 inst := check.instance(pos, typ, targs, nil, check.context()).(*Signature)
149 assert(inst.TypeParams().Len() == 0)
150 check.recordInstance(expr, targs, inst)
151 assert(len(xlist) <= len(targs))
152
153
154 check.later(func() {
155 tparams := typ.TypeParams().list()
156
157 if i, err := check.verify(pos, tparams, targs, check.context()); err != nil {
158
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
177
178
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
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
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
231 id := x.id
232 if !check.builtin(x, call, id) {
233 x.mode = invalid
234 }
235 x.expr = call
236
237 if x.mode != invalid && x.mode != constant_ {
238 check.hasCallOrRecv = true
239 }
240 return predeclaredFuncs[id].kind
241 }
242
243
244
245 cgocall := x.mode == cgofunc
246
247
248
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)
262
263
264 wasGeneric := sig.TypeParams().Len() > 0
265
266
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
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
291
292
293
294
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
299
300 targs = nil
301 xlist = nil
302 }
303 }
304
305
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
311 check.recordTypeAndValue(call.Fun, value, sig, nil)
312 }
313
314
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
325 default:
326 x.mode = value
327 x.typ = sig.results
328 }
329 x.expr = call
330 check.hasCallOrRecv = true
331
332
333
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
342
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
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
359
360
361
362
363
364
365 func (check *Checker) genericExprList(elist []ast.Expr) (resList []*operand, targsList [][]Type) {
366 if debug {
367 defer func() {
368
369 for i, x := range resList {
370 if i < len(targsList) {
371 if n := len(targsList[i]); n > 0 {
372
373 assert(n < x.typ.(*Signature).TypeParams().Len())
374 }
375 }
376 }
377 }()
378 }
379
380
381
382 infer := true
383 n := len(elist)
384 if n > 0 && check.allowVersion(go1_21) {
385 infer = false
386 }
387
388 if n == 1 {
389
390 e := elist[0]
391 var x operand
392 if ix := unpackIndexedExpr(e); ix != nil && check.indexExpr(&x, ix) {
393
394 targs := check.funcInst(nil, x.Pos(), &x, ix, infer)
395 if targs != nil {
396
397 targsList = [][]Type{targs}
398
399 x.expr = ix.orig
400 } else {
401
402
403 check.record(&x)
404 }
405 resList = []*operand{&x}
406 } else {
407
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
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
418 resList = []*operand{&x}
419 }
420 }
421 } else if n > 1 {
422
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
429 targs := check.funcInst(nil, x.Pos(), &x, ix, infer)
430 if targs != nil {
431
432 targsList[i] = targs
433
434 x.expr = ix.orig
435 } else {
436
437
438 check.record(&x)
439 }
440 } else {
441
442 check.genericExpr(&x, e)
443 }
444 resList[i] = &x
445 }
446 }
447
448 return
449 }
450
451
452
453
454
455
456
457
458
459
460
461
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
466
467
468
469
470
471
472
473
474 nargs := len(args)
475 npars := sig.params.Len()
476 ddd := hasDots(call)
477
478
479 sigParams := sig.params
480 adjusted := false
481 if sig.variadic {
482 if ddd {
483
484 if len(call.Args) == 1 && nargs > 1 {
485
486 check.errorf(inNode(call, call.Ellipsis), InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.Args[0])
487 return
488 }
489 } else {
490
491 if nargs >= npars-1 {
492
493
494
495 vars := make([]*Var, npars-1)
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...)
503 adjusted = true
504 npars = nargs
505 } else {
506
507 npars--
508 }
509 }
510 } else {
511 if ddd {
512
513 check.errorf(inNode(call, call.Ellipsis), NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
514 return
515 }
516
517 }
518
519
520 if nargs != npars {
521 var at positioner = call
522 qualifier := "not enough"
523 if nargs > npars {
524 at = args[npars].expr
525 qualifier = "too many"
526 } else {
527 at = atPos(call.Rparen)
528 }
529
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
543 var tparams []*TypeParam
544
545
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
558 var tmp Type
559 tparams, tmp = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams)
560 sigParams = tmp.(*Tuple)
561
562 for len(targs) < len(tparams) {
563 targs = append(targs, nil)
564 }
565 }
566 assert(len(tparams) == len(targs))
567
568
569 var genericArgs []int
570 if enableReverseTypeInference {
571 for i, arg := range args {
572
573 if asig, _ := arg.typ.(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
574
575
576
577
578
579
580 asig = clone(asig)
581
582
583
584
585 atparams, tmp := check.renameTParams(call.Pos(), asig.TypeParams().list(), asig)
586 asig = tmp.(*Signature)
587 asig.tparams = &TypeParamList{atparams}
588 arg.typ = asig
589 tparams = append(tparams, atparams...)
590
591 if i < len(atargs) {
592 targs = append(targs, atargs[i]...)
593 }
594
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
605 _ = len(genericArgs) > 0 && check.verifyVersionf(args[genericArgs[0]], go1_21, "implicitly instantiated function as argument")
606
607
608
609
610
611
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
617
618
619
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
627 if n > 0 {
628 rsig = check.instantiateSignature(call.Pos(), call.Fun, sig, targs[:n], xlist)
629
630
631
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
640 j := n
641 for _, i := range genericArgs {
642 arg := args[i]
643 asig := arg.typ.(*Signature)
644 k := j + asig.TypeParams().Len()
645
646 arg.typ = check.instantiateSignature(call.Pos(), arg.expr, asig, targs[j:k], nil)
647 check.record(arg)
648 j = k
649 }
650 }
651
652
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_",
669 "_Cfpvar_fp_",
670 "_Cfunc_",
671 "_Cmacro_",
672 }
673
674 func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *TypeName, wantType bool) {
675
676 var (
677 obj Object
678 index []int
679 indirect bool
680 )
681
682 sel := e.Sel.Name
683
684
685
686
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
699
700
701 if sel == "malloc" {
702 sel = "_CMalloc"
703 } else {
704 funcMode = cgofunc
705 }
706 for _, prefix := range cgoPrefixes {
707
708
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))
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
726 exps := pkg.scope.lookupIgnoringCase(sel, true)
727 if len(exps) >= 1 {
728
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
739 }
740 }
741 check.recordUse(e.Sel, exp)
742
743
744
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
784 if def != nil && def.typ == x.typ {
785 check.cycleError([]Object{def}, 0)
786 goto Error
787 }
788 case builtin:
789
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
797
798
799
800
801
802
803
804
805
806
807
808
809
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
818 if !isValid(under(x.typ)) {
819 goto Error
820 }
821
822 if index != nil {
823
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
849 if m, _ := obj.(*Func); m != nil {
850 check.objDecl(m, nil)
851 }
852
853 if x.mode == typexpr {
854
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
870
871 var params []*Var
872 if sig.params != nil {
873 params = sig.params.vars
874 }
875
876
877
878
879
880
881 name := ""
882 if len(params) > 0 && params[0].name != "" {
883
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
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
914
915 check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
916
917
918
919
920
921
922
923 disabled := true
924 if !disabled && debug {
925
926
927
928
929
930 typ := x.typ
931 if x.mode == variable {
932
933
934
935
936
937 if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
938 typ = &Pointer{base: typ}
939 }
940 }
941
942
943
944
945
946
947
948
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
954
955
956
957
958 panic("method sets and lookup don't agree")
959 }
960 }
961
962 x.mode = value
963
964
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
977 x.expr = e
978 return
979
980 Error:
981 x.mode = invalid
982 x.expr = e
983 }
984
985
986
987
988
989
990 func (check *Checker) use(args ...ast.Expr) bool { return check.useN(args, false) }
991
992
993
994
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
1010 switch n := ast.Unparen(e).(type) {
1011 case nil:
1012
1013 case *ast.Ident:
1014
1015 if n.Name == "_" {
1016 break
1017 }
1018
1019
1020
1021 var v *Var
1022 var v_used bool
1023 if lhs {
1024 if obj := check.lookup(n.Name); obj != nil {
1025
1026
1027
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
1037 }
1038 default:
1039 check.rawExpr(nil, &x, e, nil, true)
1040 }
1041 return x.mode != invalid
1042 }
1043
View as plain text