1
2
3
4
5
6
7 package types2
8
9 import (
10 "cmd/compile/internal/syntax"
11 . "internal/types/errors"
12 "strings"
13 "unicode"
14 )
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 func (check *Checker) funcInst(T *target, pos syntax.Pos, x *operand, inst *syntax.IndexExpr, infer bool) ([]Type, []syntax.Expr) {
36 assert(T != nil || inst != nil)
37
38 var instErrPos poser
39 if inst != nil {
40 instErrPos = inst.Pos()
41 } else {
42 instErrPos = pos
43 }
44 versionErr := !check.verifyVersionf(instErrPos, go1_18, "function instantiation")
45
46
47 var targs []Type
48 var xlist []syntax.Expr
49 if inst != nil {
50 xlist = syntax.UnpackListExpr(inst.Index)
51 targs = check.typeList(xlist)
52 if targs == nil {
53 x.mode = invalid
54 x.expr = inst
55 return nil, nil
56 }
57 assert(len(targs) == len(xlist))
58 }
59
60
61
62
63 sig := x.typ.(*Signature)
64 got, want := len(targs), sig.TypeParams().Len()
65 if got > want {
66
67 check.errorf(xlist[got-1], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
68 x.mode = invalid
69 x.expr = inst
70 return nil, nil
71 }
72
73 if got < want {
74 if !infer {
75 return targs, xlist
76 }
77
78
79
80
81
82
83
84
85
86
87
88 var args []*operand
89 var params []*Var
90 var reverse bool
91 if T != nil && sig.tparams != nil {
92 if !versionErr && !check.allowVersion(check.pkg, instErrPos, go1_21) {
93 if inst != nil {
94 check.versionErrorf(instErrPos, go1_21, "partially instantiated function in assignment")
95 } else {
96 check.versionErrorf(instErrPos, go1_21, "implicitly instantiated function in assignment")
97 }
98 }
99 gsig := NewSignatureType(nil, nil, nil, sig.params, sig.results, sig.variadic)
100 params = []*Var{NewVar(x.Pos(), check.pkg, "", gsig)}
101
102
103
104 expr := syntax.NewName(x.Pos(), T.desc)
105 args = []*operand{{mode: value, expr: expr, typ: T.sig}}
106 reverse = true
107 }
108
109
110
111 tparams, params2 := check.renameTParams(pos, sig.TypeParams().list(), NewTuple(params...))
112
113 targs = check.infer(pos, tparams, targs, params2.(*Tuple), args, reverse)
114 if targs == nil {
115
116 x.mode = invalid
117 x.expr = inst
118 return nil, nil
119 }
120 got = len(targs)
121 }
122 assert(got == want)
123
124
125 expr := x.expr
126 if inst != nil {
127 expr = inst
128 }
129 sig = check.instantiateSignature(x.Pos(), expr, sig, targs, xlist)
130
131 x.typ = sig
132 x.mode = value
133 x.expr = expr
134 return nil, nil
135 }
136
137 func (check *Checker) instantiateSignature(pos syntax.Pos, expr syntax.Expr, typ *Signature, targs []Type, xlist []syntax.Expr) (res *Signature) {
138 assert(check != nil)
139 assert(len(targs) == typ.TypeParams().Len())
140
141 if check.conf.Trace {
142 check.trace(pos, "-- instantiating signature %s with %s", typ, targs)
143 check.indent++
144 defer func() {
145 check.indent--
146 check.trace(pos, "=> %s (under = %s)", res, res.Underlying())
147 }()
148 }
149
150 inst := check.instance(pos, typ, targs, nil, check.context()).(*Signature)
151 assert(inst.TypeParams().Len() == 0)
152 check.recordInstance(expr, targs, inst)
153 assert(len(xlist) <= len(targs))
154
155
156 check.later(func() {
157 tparams := typ.TypeParams().list()
158 if i, err := check.verify(pos, tparams, targs, check.context()); err != nil {
159
160 pos := pos
161 if i < len(xlist) {
162 pos = syntax.StartPos(xlist[i])
163 }
164 check.softErrorf(pos, InvalidTypeArg, "%s", err)
165 } else {
166 check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
167 }
168 }).describef(pos, "verify instantiation")
169
170 return inst
171 }
172
173 func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
174 var inst *syntax.IndexExpr
175 if iexpr, _ := call.Fun.(*syntax.IndexExpr); iexpr != nil {
176 if check.indexExpr(x, iexpr) {
177
178
179
180 assert(x.mode == value)
181 inst = iexpr
182 }
183 x.expr = iexpr
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.ArgList...)
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.ArgList); n {
205 case 0:
206 check.errorf(call, WrongArgCount, "missing argument in conversion to %s", T)
207 case 1:
208 check.expr(nil, x, call.ArgList[0])
209 if x.mode != invalid {
210 if t, _ := under(T).(*Interface); t != nil && !isTypeParam(T) {
211 if !t.IsMethodSet() {
212 check.errorf(call, MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
213 break
214 }
215 }
216 if call.HasDots {
217 check.errorf(call.ArgList[0], BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
218 break
219 }
220 check.conversion(x, T)
221 }
222 default:
223 check.use(call.ArgList...)
224 check.errorf(call.ArgList[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 sig, _ := coreType(x.typ).(*Signature)
249 if sig == nil {
250 check.errorf(x, InvalidCall, invalidOp+"cannot call non-function %s", x)
251 x.mode = invalid
252 x.expr = call
253 return statement
254 }
255
256
257 wasGeneric := sig.TypeParams().Len() > 0
258
259
260 var xlist []syntax.Expr
261 var targs []Type
262 if inst != nil {
263 xlist = syntax.UnpackListExpr(inst.Index)
264 targs = check.typeList(xlist)
265 if targs == nil {
266 check.use(call.ArgList...)
267 x.mode = invalid
268 x.expr = call
269 return statement
270 }
271 assert(len(targs) == len(xlist))
272
273
274 got, want := len(targs), sig.TypeParams().Len()
275 if got > want {
276 check.errorf(xlist[want], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
277 check.use(call.ArgList...)
278 x.mode = invalid
279 x.expr = call
280 return statement
281 }
282
283
284
285
286
287
288 if got == want && want > 0 {
289 check.verifyVersionf(inst, go1_18, "function instantiation")
290 sig = check.instantiateSignature(inst.Pos(), inst, sig, targs, xlist)
291
292
293 targs = nil
294 xlist = nil
295 }
296 }
297
298
299 args, atargs, atxlist := check.genericExprList(call.ArgList)
300 sig = check.arguments(call, sig, targs, xlist, args, atargs, atxlist)
301
302 if wasGeneric && sig.TypeParams().Len() == 0 {
303
304 check.recordTypeAndValue(call.Fun, value, sig, nil)
305 }
306
307
308 switch sig.results.Len() {
309 case 0:
310 x.mode = novalue
311 case 1:
312 if cgocall {
313 x.mode = commaerr
314 } else {
315 x.mode = value
316 }
317 x.typ = sig.results.vars[0].typ
318 default:
319 x.mode = value
320 x.typ = sig.results
321 }
322 x.expr = call
323 check.hasCallOrRecv = true
324
325
326
327 if x.mode == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ) {
328 x.mode = invalid
329 }
330
331 return statement
332 }
333
334
335
336 func (check *Checker) exprList(elist []syntax.Expr) (xlist []*operand) {
337 if n := len(elist); n == 1 {
338 xlist, _ = check.multiExpr(elist[0], false)
339 } else if n > 1 {
340
341 xlist = make([]*operand, n)
342 for i, e := range elist {
343 var x operand
344 check.expr(nil, &x, e)
345 xlist[i] = &x
346 }
347 }
348 return
349 }
350
351
352
353
354
355
356
357
358 func (check *Checker) genericExprList(elist []syntax.Expr) (resList []*operand, targsList [][]Type, xlistList [][]syntax.Expr) {
359 if debug {
360 defer func() {
361
362 assert(len(targsList) == len(xlistList))
363
364 for i, x := range resList {
365 if i < len(targsList) {
366 if n := len(targsList[i]); n > 0 {
367
368 assert(n < x.typ.(*Signature).TypeParams().Len())
369 }
370 }
371 }
372 }()
373 }
374
375
376
377 infer := true
378 n := len(elist)
379 if n > 0 && check.allowVersion(check.pkg, elist[0], go1_21) {
380 infer = false
381 }
382
383 if n == 1 {
384
385 e := elist[0]
386 var x operand
387 if inst, _ := e.(*syntax.IndexExpr); inst != nil && check.indexExpr(&x, inst) {
388
389 targs, xlist := check.funcInst(nil, x.Pos(), &x, inst, infer)
390 if targs != nil {
391
392 targsList = [][]Type{targs}
393 xlistList = [][]syntax.Expr{xlist}
394
395 x.expr = inst
396 } else {
397
398
399 check.record(&x)
400 }
401 resList = []*operand{&x}
402 } else {
403
404 check.rawExpr(nil, &x, e, nil, true)
405 check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
406 if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
407
408 resList = make([]*operand, t.Len())
409 for i, v := range t.vars {
410 resList[i] = &operand{mode: value, expr: e, typ: v.typ}
411 }
412 } else {
413
414 resList = []*operand{&x}
415 }
416 }
417 } else if n > 1 {
418
419 resList = make([]*operand, n)
420 targsList = make([][]Type, n)
421 xlistList = make([][]syntax.Expr, n)
422 for i, e := range elist {
423 var x operand
424 if inst, _ := e.(*syntax.IndexExpr); inst != nil && check.indexExpr(&x, inst) {
425
426 targs, xlist := check.funcInst(nil, x.Pos(), &x, inst, infer)
427 if targs != nil {
428
429 targsList[i] = targs
430 xlistList[i] = xlist
431
432 x.expr = inst
433 } else {
434
435
436 check.record(&x)
437 }
438 } else {
439
440 check.genericExpr(&x, e)
441 }
442 resList[i] = &x
443 }
444 }
445
446 return
447 }
448
449
450
451
452
453
454
455
456
457
458
459
460
461 func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []Type, xlist []syntax.Expr, args []*operand, atargs [][]Type, atxlist [][]syntax.Expr) (rsig *Signature) {
462 rsig = sig
463
464
465
466
467
468
469
470
471
472
473 nargs := len(args)
474 npars := sig.params.Len()
475 ddd := call.HasDots
476
477
478 sigParams := sig.params
479 adjusted := false
480 if sig.variadic {
481 if ddd {
482
483 if len(call.ArgList) == 1 && nargs > 1 {
484
485
486 check.errorf(call, InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.ArgList[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
514 check.errorf(call, NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
515 return
516 }
517
518 }
519
520
521 if nargs != npars {
522 var at poser = call
523 qualifier := "not enough"
524 if nargs > npars {
525 at = args[npars].expr
526 qualifier = "too many"
527 } else if nargs > 0 {
528 at = args[nargs-1].expr
529 }
530
531 var params []*Var
532 if sig.params != nil {
533 params = sig.params.vars
534 }
535 var err error_
536 err.code = WrongArgCount
537 err.errorf(at, "%s arguments in call to %s", qualifier, call.Fun)
538 err.errorf(nopos, "have %s", check.typesSummary(operandTypes(args), false))
539 err.errorf(nopos, "want %s", check.typesSummary(varTypes(params), sig.variadic))
540 check.report(&err)
541 return
542 }
543
544
545 var tparams []*TypeParam
546
547
548 n := sig.TypeParams().Len()
549 if n > 0 {
550 if !check.allowVersion(check.pkg, call.Pos(), go1_18) {
551 if iexpr, _ := call.Fun.(*syntax.IndexExpr); iexpr != nil {
552 check.versionErrorf(iexpr, go1_18, "function instantiation")
553 } else {
554 check.versionErrorf(call, 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 targs = check.infer(call.Pos(), tparams, targs, sigParams, args, false)
614 if targs == nil {
615
616
617
618
619 return
620 }
621
622
623 if n > 0 {
624 rsig = check.instantiateSignature(call.Pos(), call.Fun, sig, targs[:n], xlist)
625
626
627
628 if adjusted {
629 sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
630 } else {
631 sigParams = rsig.params
632 }
633 }
634
635
636 j := n
637 for _, i := range genericArgs {
638 arg := args[i]
639 asig := arg.typ.(*Signature)
640 k := j + asig.TypeParams().Len()
641
642 arg.typ = check.instantiateSignature(call.Pos(), arg.expr, asig, targs[j:k], nil)
643 check.record(arg)
644 j = k
645 }
646 }
647
648
649 if len(args) > 0 {
650 context := check.sprintf("argument to %s", call.Fun)
651 for i, a := range args {
652 check.assignment(a, sigParams.vars[i].typ, context)
653 }
654 }
655
656 return
657 }
658
659 var cgoPrefixes = [...]string{
660 "_Ciconst_",
661 "_Cfconst_",
662 "_Csconst_",
663 "_Ctype_",
664 "_Cvar_",
665 "_Cfpvar_fp_",
666 "_Cfunc_",
667 "_Cmacro_",
668 }
669
670 func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *TypeName, wantType bool) {
671
672 var (
673 obj Object
674 index []int
675 indirect bool
676 )
677
678 sel := e.Sel.Value
679
680
681
682
683 if ident, ok := e.X.(*syntax.Name); ok {
684 obj := check.lookup(ident.Value)
685 if pname, _ := obj.(*PkgName); pname != nil {
686 assert(pname.pkg == check.pkg)
687 check.recordUse(ident, pname)
688 pname.used = true
689 pkg := pname.imported
690
691 var exp Object
692 funcMode := value
693 if pkg.cgo {
694
695
696
697 if sel == "malloc" {
698 sel = "_CMalloc"
699 } else {
700 funcMode = cgofunc
701 }
702 for _, prefix := range cgoPrefixes {
703
704
705 _, exp = check.scope.LookupParent(prefix+sel, check.pos)
706 if exp != nil {
707 break
708 }
709 }
710 if exp == nil {
711 check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", syntax.Expr(e))
712 goto Error
713 }
714 check.objDecl(exp, nil)
715 } else {
716 exp = pkg.scope.Lookup(sel)
717 if exp == nil {
718 if !pkg.fake {
719 check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", syntax.Expr(e))
720 }
721 goto Error
722 }
723 if !exp.Exported() {
724 check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", sel, pkg.name)
725
726 }
727 }
728 check.recordUse(e.Sel, exp)
729
730
731
732 switch exp := exp.(type) {
733 case *Const:
734 assert(exp.Val() != nil)
735 x.mode = constant_
736 x.typ = exp.typ
737 x.val = exp.val
738 case *TypeName:
739 x.mode = typexpr
740 x.typ = exp.typ
741 case *Var:
742 x.mode = variable
743 x.typ = exp.typ
744 if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
745 x.typ = x.typ.(*Pointer).base
746 }
747 case *Func:
748 x.mode = funcMode
749 x.typ = exp.typ
750 if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
751 x.mode = value
752 x.typ = x.typ.(*Signature).results.vars[0].typ
753 }
754 case *Builtin:
755 x.mode = builtin
756 x.typ = exp.typ
757 x.id = exp.id
758 default:
759 check.dump("%v: unexpected object %v", atPos(e.Sel), exp)
760 unreachable()
761 }
762 x.expr = e
763 return
764 }
765 }
766
767 check.exprOrType(x, e.X, false)
768 switch x.mode {
769 case typexpr:
770
771 if def != nil && def.typ == x.typ {
772 check.cycleError([]Object{def})
773 goto Error
774 }
775 case builtin:
776 check.errorf(e.Pos(), UncalledBuiltin, "cannot select on %s", x)
777 goto Error
778 case invalid:
779 goto Error
780 }
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796 if wantType {
797 check.errorf(e.Sel, NotAType, "%s is not a type", syntax.Expr(e))
798 goto Error
799 }
800
801 obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
802 if obj == nil {
803
804 if !isValid(under(x.typ)) {
805 goto Error
806 }
807
808 if index != nil {
809
810 check.errorf(e.Sel, AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
811 goto Error
812 }
813
814 if indirect {
815 if x.mode == typexpr {
816 check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel)
817 } else {
818 check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
819 }
820 goto Error
821 }
822
823 var why string
824 if isInterfacePtr(x.typ) {
825 why = check.interfacePtrError(x.typ)
826 } else {
827 why = check.sprintf("type %s has no field or method %s", x.typ, sel)
828
829
830
831 if len(sel) > 0 {
832 var changeCase string
833 if r := rune(sel[0]); unicode.IsUpper(r) {
834 changeCase = string(unicode.ToLower(r)) + sel[1:]
835 } else {
836 changeCase = string(unicode.ToUpper(r)) + sel[1:]
837 }
838 if obj, _, _ = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil {
839 why += ", but does have " + changeCase
840 }
841 }
842 }
843 check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
844 goto Error
845 }
846
847
848 if m, _ := obj.(*Func); m != nil {
849 check.objDecl(m, nil)
850 }
851
852 if x.mode == typexpr {
853
854 m, _ := obj.(*Func)
855 if m == nil {
856
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{NewVar(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 x.mode = value
918
919
920 sig := *obj.typ.(*Signature)
921 sig.recv = nil
922 x.typ = &sig
923
924 check.addDeclDep(obj)
925
926 default:
927 unreachable()
928 }
929 }
930
931
932 x.expr = e
933 return
934
935 Error:
936 x.mode = invalid
937 x.expr = e
938 }
939
940
941
942
943
944
945 func (check *Checker) use(args ...syntax.Expr) bool { return check.useN(args, false) }
946
947
948
949
950 func (check *Checker) useLHS(args ...syntax.Expr) bool { return check.useN(args, true) }
951
952 func (check *Checker) useN(args []syntax.Expr, lhs bool) bool {
953 ok := true
954 for _, e := range args {
955 if !check.use1(e, lhs) {
956 ok = false
957 }
958 }
959 return ok
960 }
961
962 func (check *Checker) use1(e syntax.Expr, lhs bool) bool {
963 var x operand
964 x.mode = value
965 switch n := syntax.Unparen(e).(type) {
966 case nil:
967
968 case *syntax.Name:
969
970 if n.Value == "_" {
971 break
972 }
973
974
975
976 var v *Var
977 var v_used bool
978 if lhs {
979 if _, obj := check.scope.LookupParent(n.Value, nopos); obj != nil {
980
981
982
983 if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
984 v = w
985 v_used = v.used
986 }
987 }
988 }
989 check.exprOrType(&x, n, true)
990 if v != nil {
991 v.used = v_used
992 }
993 case *syntax.ListExpr:
994 return check.useN(n.ElemList, lhs)
995 default:
996 check.rawExpr(nil, &x, e, nil, true)
997 }
998 return x.mode != invalid
999 }
1000
View as plain text