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, _ := T.Underlying().(*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, 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)
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 builtin:
783
784 check.errorf(e.Sel, UncalledBuiltin, "invalid use of %s in selector expression", x)
785 goto Error
786 case invalid:
787 goto Error
788 }
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804 if wantType {
805 check.errorf(e.Sel, NotAType, "%s is not a type", ast.Expr(e))
806 goto Error
807 }
808
809 obj, index, indirect = lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel, false)
810 if obj == nil {
811
812 if !isValid(x.typ.Underlying()) {
813 goto Error
814 }
815
816 if index != nil {
817
818 check.errorf(e.Sel, AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
819 goto Error
820 }
821
822 if indirect {
823 if x.mode == typexpr {
824 check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel)
825 } else {
826 check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
827 }
828 goto Error
829 }
830
831 var why string
832 if isInterfacePtr(x.typ) {
833 why = check.interfacePtrError(x.typ)
834 } else {
835 alt, _, _ := lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel, true)
836 why = check.lookupError(x.typ, sel, alt, false)
837 }
838 check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
839 goto Error
840 }
841
842
843 if m, _ := obj.(*Func); m != nil {
844 check.objDecl(m)
845 }
846
847 if x.mode == typexpr {
848
849 m, _ := obj.(*Func)
850 if m == nil {
851 check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
852 goto Error
853 }
854
855 check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
856
857 sig := m.typ.(*Signature)
858 if sig.recv == nil {
859 check.error(e, InvalidDeclCycle, "illegal cycle in method declaration")
860 goto Error
861 }
862
863
864
865 var params []*Var
866 if sig.params != nil {
867 params = sig.params.vars
868 }
869
870
871
872
873
874
875 name := ""
876 if len(params) > 0 && params[0].name != "" {
877
878 name = sig.recv.name
879 if name == "" {
880 name = "_"
881 }
882 }
883 params = append([]*Var{NewParam(sig.recv.pos, sig.recv.pkg, name, x.typ)}, params...)
884 x.mode = value
885 x.typ = &Signature{
886 tparams: sig.tparams,
887 params: NewTuple(params...),
888 results: sig.results,
889 variadic: sig.variadic,
890 }
891
892 check.addDeclDep(m)
893
894 } else {
895
896 switch obj := obj.(type) {
897 case *Var:
898 check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
899 if x.mode == variable || indirect {
900 x.mode = variable
901 } else {
902 x.mode = value
903 }
904 x.typ = obj.typ
905
906 case *Func:
907
908
909 check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
910
911
912
913
914
915
916
917 disabled := true
918 if !disabled && debug {
919
920
921
922
923
924 typ := x.typ
925 if x.mode == variable {
926
927
928
929
930
931 if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
932 typ = &Pointer{base: typ}
933 }
934 }
935
936
937
938
939
940
941
942
943 mset := NewMethodSet(typ)
944 if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
945 check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
946 check.dump("%s\n", mset)
947
948
949
950
951
952 panic("method sets and lookup don't agree")
953 }
954 }
955
956 x.mode = value
957
958
959 sig := *obj.typ.(*Signature)
960 sig.recv = nil
961 x.typ = &sig
962
963 check.addDeclDep(obj)
964
965 default:
966 panic("unreachable")
967 }
968 }
969
970
971 x.expr = e
972 return
973
974 Error:
975 x.mode = invalid
976 x.typ = Typ[Invalid]
977 x.expr = e
978 }
979
980
981
982
983
984
985 func (check *Checker) use(args ...ast.Expr) bool { return check.useN(args, false) }
986
987
988
989
990 func (check *Checker) useLHS(args ...ast.Expr) bool { return check.useN(args, true) }
991
992 func (check *Checker) useN(args []ast.Expr, lhs bool) bool {
993 ok := true
994 for _, e := range args {
995 if !check.use1(e, lhs) {
996 ok = false
997 }
998 }
999 return ok
1000 }
1001
1002 func (check *Checker) use1(e ast.Expr, lhs bool) bool {
1003 var x operand
1004 x.mode = value
1005 switch n := ast.Unparen(e).(type) {
1006 case nil:
1007
1008 case *ast.Ident:
1009
1010 if n.Name == "_" {
1011 break
1012 }
1013
1014
1015
1016 var v *Var
1017 var v_used bool
1018 if lhs {
1019 if obj := check.lookup(n.Name); obj != nil {
1020
1021
1022
1023 if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
1024 v = w
1025 v_used = check.usedVars[v]
1026 }
1027 }
1028 }
1029 check.exprOrType(&x, n, true)
1030 if v != nil {
1031 check.usedVars[v] = v_used
1032 }
1033 default:
1034 check.rawExpr(nil, &x, e, nil, true)
1035 }
1036 return x.mode != invalid
1037 }
1038
View as plain text