1
2
3
4
5
6
7 package types2
8
9 import (
10 "cmd/compile/internal/syntax"
11 "strings"
12 "unicode"
13 )
14
15
16
17 func (check *Checker) funcInst(x *operand, inst *syntax.IndexExpr) {
18 if !check.allowVersion(check.pkg, 1, 18) {
19 check.versionErrorf(inst.Pos(), "go1.18", "function instantiation")
20 }
21
22 xlist := unpackExpr(inst.Index)
23 targs := check.typeList(xlist)
24 if targs == nil {
25 x.mode = invalid
26 x.expr = inst
27 return
28 }
29 assert(len(targs) == len(xlist))
30
31
32 sig := x.typ.(*Signature)
33 got, want := len(targs), sig.TypeParams().Len()
34 if !useConstraintTypeInference && got != want || got > want {
35 check.errorf(xlist[got-1], "got %d type arguments but want %d", got, want)
36 x.mode = invalid
37 x.expr = inst
38 return
39 }
40
41 if got < want {
42 targs = check.infer(inst.Pos(), sig.TypeParams().list(), targs, nil, nil)
43 if targs == nil {
44
45 x.mode = invalid
46 x.expr = inst
47 return
48 }
49 got = len(targs)
50 }
51 assert(got == want)
52
53
54 res := check.instantiateSignature(x.Pos(), sig, targs, xlist)
55 assert(res.TypeParams().Len() == 0)
56 check.recordInstance(inst.X, targs, res)
57 x.typ = res
58 x.mode = value
59 x.expr = inst
60 }
61
62 func (check *Checker) instantiateSignature(pos syntax.Pos, typ *Signature, targs []Type, xlist []syntax.Expr) (res *Signature) {
63 assert(check != nil)
64 assert(len(targs) == typ.TypeParams().Len())
65
66 if check.conf.Trace {
67 check.trace(pos, "-- instantiating %s with %s", typ, targs)
68 check.indent++
69 defer func() {
70 check.indent--
71 check.trace(pos, "=> %s (under = %s)", res, res.Underlying())
72 }()
73 }
74
75 inst := check.instance(pos, typ, targs, check.bestContext(nil)).(*Signature)
76 assert(len(xlist) <= len(targs))
77
78
79 check.later(func() {
80 tparams := typ.TypeParams().list()
81 if i, err := check.verify(pos, tparams, targs); err != nil {
82
83 pos := pos
84 if i < len(xlist) {
85 pos = syntax.StartPos(xlist[i])
86 }
87 check.softErrorf(pos, "%s", err)
88 } else {
89 check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
90 }
91 })
92
93 return inst
94 }
95
96 func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
97 var inst *syntax.IndexExpr
98 if iexpr, _ := call.Fun.(*syntax.IndexExpr); iexpr != nil {
99 if check.indexExpr(x, iexpr) {
100
101
102
103 assert(x.mode == value)
104 inst = iexpr
105 }
106 x.expr = iexpr
107 check.record(x)
108 } else {
109 check.exprOrType(x, call.Fun, true)
110 }
111
112
113 switch x.mode {
114 case invalid:
115 check.use(call.ArgList...)
116 x.expr = call
117 return statement
118
119 case typexpr:
120
121 check.nonGeneric(x)
122 if x.mode == invalid {
123 return conversion
124 }
125 T := x.typ
126 x.mode = invalid
127 switch n := len(call.ArgList); n {
128 case 0:
129 check.errorf(call, "missing argument in conversion to %s", T)
130 case 1:
131 check.expr(x, call.ArgList[0])
132 if x.mode != invalid {
133 if t, _ := under(T).(*Interface); t != nil && !isTypeParam(T) {
134 if !t.IsMethodSet() {
135 check.errorf(call, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
136 break
137 }
138 }
139 if call.HasDots {
140 check.errorf(call.ArgList[0], "invalid use of ... in type conversion to %s", T)
141 break
142 }
143 check.conversion(x, T)
144 }
145 default:
146 check.use(call.ArgList...)
147 check.errorf(call.ArgList[n-1], "too many arguments in conversion to %s", T)
148 }
149 x.expr = call
150 return conversion
151
152 case builtin:
153
154 id := x.id
155 if !check.builtin(x, call, id) {
156 x.mode = invalid
157 }
158 x.expr = call
159
160 if x.mode != invalid && x.mode != constant_ {
161 check.hasCallOrRecv = true
162 }
163 return predeclaredFuncs[id].kind
164 }
165
166
167
168 cgocall := x.mode == cgofunc
169
170
171 sig, _ := coreType(x.typ).(*Signature)
172 if sig == nil {
173 check.errorf(x, invalidOp+"cannot call non-function %s", x)
174 x.mode = invalid
175 x.expr = call
176 return statement
177 }
178
179
180 var xlist []syntax.Expr
181 var targs []Type
182 if inst != nil {
183 xlist = unpackExpr(inst.Index)
184 targs = check.typeList(xlist)
185 if targs == nil {
186 check.use(call.ArgList...)
187 x.mode = invalid
188 x.expr = call
189 return statement
190 }
191 assert(len(targs) == len(xlist))
192
193
194 got, want := len(targs), sig.TypeParams().Len()
195 if got > want {
196 check.errorf(xlist[want], "got %d type arguments but want %d", got, want)
197 check.use(call.ArgList...)
198 x.mode = invalid
199 x.expr = call
200 return statement
201 }
202 }
203
204
205 args, _ := check.exprList(call.ArgList, false)
206 isGeneric := sig.TypeParams().Len() > 0
207 sig = check.arguments(call, sig, targs, args, xlist)
208
209 if isGeneric && sig.TypeParams().Len() == 0 {
210
211 check.recordTypeAndValue(call.Fun, value, sig, nil)
212 }
213
214
215 switch sig.results.Len() {
216 case 0:
217 x.mode = novalue
218 case 1:
219 if cgocall {
220 x.mode = commaerr
221 } else {
222 x.mode = value
223 }
224 x.typ = sig.results.vars[0].typ
225 default:
226 x.mode = value
227 x.typ = sig.results
228 }
229 x.expr = call
230 check.hasCallOrRecv = true
231
232
233
234 if x.mode == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ) {
235 x.mode = invalid
236 }
237
238 return statement
239 }
240
241 func (check *Checker) exprList(elist []syntax.Expr, allowCommaOk bool) (xlist []*operand, commaOk bool) {
242 switch len(elist) {
243 case 0:
244
245
246 case 1:
247
248 e := elist[0]
249 var x operand
250 check.multiExpr(&x, e)
251 if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
252
253 xlist = make([]*operand, t.Len())
254 for i, v := range t.vars {
255 xlist[i] = &operand{mode: value, expr: e, typ: v.typ}
256 }
257 break
258 }
259
260
261 xlist = []*operand{&x}
262 if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
263 x.mode = value
264 xlist = append(xlist, &operand{mode: value, expr: e, typ: Typ[UntypedBool]})
265 commaOk = true
266 }
267
268 default:
269
270 xlist = make([]*operand, len(elist))
271 for i, e := range elist {
272 var x operand
273 check.expr(&x, e)
274 xlist[i] = &x
275 }
276 }
277
278 return
279 }
280
281
282 func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []Type, args []*operand, xlist []syntax.Expr) (rsig *Signature) {
283 rsig = sig
284
285
286 for _, a := range args {
287 switch a.mode {
288 case typexpr:
289 check.errorf(a, "%s used as value", a)
290 return
291 case invalid:
292 return
293 }
294 }
295
296
297
298
299
300
301
302
303
304
305 nargs := len(args)
306 npars := sig.params.Len()
307 ddd := call.HasDots
308
309
310 sigParams := sig.params
311 adjusted := false
312 if sig.variadic {
313 if ddd {
314
315 if len(call.ArgList) == 1 && nargs > 1 {
316
317
318 check.errorf(call, "cannot use ... with %d-valued %s", nargs, call.ArgList[0])
319 return
320 }
321 } else {
322
323 if nargs >= npars-1 {
324
325
326
327 vars := make([]*Var, npars-1)
328 copy(vars, sig.params.vars)
329 last := sig.params.vars[npars-1]
330 typ := last.typ.(*Slice).elem
331 for len(vars) < nargs {
332 vars = append(vars, NewParam(last.pos, last.pkg, last.name, typ))
333 }
334 sigParams = NewTuple(vars...)
335 adjusted = true
336 npars = nargs
337 } else {
338
339 npars--
340 }
341 }
342 } else {
343 if ddd {
344
345
346 check.errorf(call, "cannot use ... in call to non-variadic %s", call.Fun)
347 return
348 }
349
350 }
351
352
353 if nargs != npars {
354 var at poser = call
355 qualifier := "not enough"
356 if nargs > npars {
357 at = args[npars].expr
358 qualifier = "too many"
359 } else if nargs > 0 {
360 at = args[nargs-1].expr
361 }
362
363 var params []*Var
364 if sig.params != nil {
365 params = sig.params.vars
366 }
367 var err error_
368 err.errorf(at, "%s arguments in call to %s", qualifier, call.Fun)
369 err.errorf(nopos, "have %s", check.typesSummary(operandTypes(args), false))
370 err.errorf(nopos, "want %s", check.typesSummary(varTypes(params), sig.variadic))
371 check.report(&err)
372 return
373 }
374
375
376 if sig.TypeParams().Len() > 0 {
377 if !check.allowVersion(check.pkg, 1, 18) {
378 if iexpr, _ := call.Fun.(*syntax.IndexExpr); iexpr != nil {
379 check.versionErrorf(iexpr.Pos(), "go1.18", "function instantiation")
380 } else {
381 check.versionErrorf(call.Pos(), "go1.18", "implicit function instantiation")
382 }
383 }
384 targs := check.infer(call.Pos(), sig.TypeParams().list(), targs, sigParams, args)
385 if targs == nil {
386 return
387 }
388
389
390 rsig = check.instantiateSignature(call.Pos(), sig, targs, xlist)
391 assert(rsig.TypeParams().Len() == 0)
392 check.recordInstance(call.Fun, targs, rsig)
393
394
395
396
397 if adjusted {
398 sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(sig.TypeParams().list(), targs), nil).(*Tuple)
399 } else {
400 sigParams = rsig.params
401 }
402 }
403
404
405 if len(args) > 0 {
406 context := check.sprintf("argument to %s", call.Fun)
407 for i, a := range args {
408 check.assignment(a, sigParams.vars[i].typ, context)
409 }
410 }
411
412 return
413 }
414
415 var cgoPrefixes = [...]string{
416 "_Ciconst_",
417 "_Cfconst_",
418 "_Csconst_",
419 "_Ctype_",
420 "_Cvar_",
421 "_Cfpvar_fp_",
422 "_Cfunc_",
423 "_Cmacro_",
424 }
425
426 func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
427
428 var (
429 obj Object
430 index []int
431 indirect bool
432 )
433
434 sel := e.Sel.Value
435
436
437
438
439 if ident, ok := e.X.(*syntax.Name); ok {
440 obj := check.lookup(ident.Value)
441 if pname, _ := obj.(*PkgName); pname != nil {
442 assert(pname.pkg == check.pkg)
443 check.recordUse(ident, pname)
444 pname.used = true
445 pkg := pname.imported
446
447 var exp Object
448 funcMode := value
449 if pkg.cgo {
450
451
452
453 if sel == "malloc" {
454 sel = "_CMalloc"
455 } else {
456 funcMode = cgofunc
457 }
458 for _, prefix := range cgoPrefixes {
459
460
461 _, exp = check.scope.LookupParent(prefix+sel, check.pos)
462 if exp != nil {
463 break
464 }
465 }
466 if exp == nil {
467 check.errorf(e.Sel, "%s not declared by package C", sel)
468 goto Error
469 }
470 check.objDecl(exp, nil)
471 } else {
472 exp = pkg.scope.Lookup(sel)
473 if exp == nil {
474 if !pkg.fake {
475 if check.conf.CompilerErrorMessages {
476 check.errorf(e.Sel, "undefined: %s.%s", pkg.name, sel)
477 } else {
478 check.errorf(e.Sel, "%s not declared by package %s", sel, pkg.name)
479 }
480 }
481 goto Error
482 }
483 if !exp.Exported() {
484 check.errorf(e.Sel, "%s not exported by package %s", sel, pkg.name)
485
486 }
487 }
488 check.recordUse(e.Sel, exp)
489
490
491
492 switch exp := exp.(type) {
493 case *Const:
494 assert(exp.Val() != nil)
495 x.mode = constant_
496 x.typ = exp.typ
497 x.val = exp.val
498 case *TypeName:
499 x.mode = typexpr
500 x.typ = exp.typ
501 case *Var:
502 x.mode = variable
503 x.typ = exp.typ
504 if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
505 x.typ = x.typ.(*Pointer).base
506 }
507 case *Func:
508 x.mode = funcMode
509 x.typ = exp.typ
510 if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
511 x.mode = value
512 x.typ = x.typ.(*Signature).results.vars[0].typ
513 }
514 case *Builtin:
515 x.mode = builtin
516 x.typ = exp.typ
517 x.id = exp.id
518 default:
519 check.dump("%v: unexpected object %v", posFor(e.Sel), exp)
520 unreachable()
521 }
522 x.expr = e
523 return
524 }
525 }
526
527 check.exprOrType(x, e.X, false)
528 switch x.mode {
529 case typexpr:
530
531 if def != nil && x.typ == def {
532 check.cycleError([]Object{def.obj})
533 goto Error
534 }
535 case builtin:
536 check.errorf(e.Pos(), "cannot select on %s", x)
537 goto Error
538 case invalid:
539 goto Error
540 }
541
542 obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
543 if obj == nil {
544
545 if under(x.typ) == Typ[Invalid] {
546 goto Error
547 }
548
549 if index != nil {
550
551 check.errorf(e.Sel, "ambiguous selector %s.%s", x.expr, sel)
552 goto Error
553 }
554
555 if indirect {
556 check.errorf(e.Sel, "cannot call pointer method %s on %s", sel, x.typ)
557 goto Error
558 }
559
560 var why string
561 if isInterfacePtr(x.typ) {
562 why = check.interfacePtrError(x.typ)
563 } else {
564 why = check.sprintf("type %s has no field or method %s", x.typ, sel)
565
566
567
568 if len(sel) > 0 {
569 var changeCase string
570 if r := rune(sel[0]); unicode.IsUpper(r) {
571 changeCase = string(unicode.ToLower(r)) + sel[1:]
572 } else {
573 changeCase = string(unicode.ToUpper(r)) + sel[1:]
574 }
575 if obj, _, _ = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil {
576 why += ", but does have " + changeCase
577 }
578 }
579 }
580 check.errorf(e.Sel, "%s.%s undefined (%s)", x.expr, sel, why)
581 goto Error
582 }
583
584
585 if m, _ := obj.(*Func); m != nil {
586 check.objDecl(m, nil)
587 }
588
589 if x.mode == typexpr {
590
591 m, _ := obj.(*Func)
592 if m == nil {
593
594 check.errorf(e.Sel, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
595 goto Error
596 }
597
598 check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
599
600 sig := m.typ.(*Signature)
601 if sig.recv == nil {
602 check.error(e, "illegal cycle in method declaration")
603 goto Error
604 }
605
606
607
608 var params []*Var
609 if sig.params != nil {
610 params = sig.params.vars
611 }
612
613
614
615
616
617
618 name := ""
619 if len(params) > 0 && params[0].name != "" {
620
621 name = sig.recv.name
622 if name == "" {
623 name = "_"
624 }
625 }
626 params = append([]*Var{NewVar(sig.recv.pos, sig.recv.pkg, name, x.typ)}, params...)
627 x.mode = value
628 x.typ = &Signature{
629 tparams: sig.tparams,
630 params: NewTuple(params...),
631 results: sig.results,
632 variadic: sig.variadic,
633 }
634
635 check.addDeclDep(m)
636
637 } else {
638
639 switch obj := obj.(type) {
640 case *Var:
641 check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
642 if x.mode == variable || indirect {
643 x.mode = variable
644 } else {
645 x.mode = value
646 }
647 x.typ = obj.typ
648
649 case *Func:
650
651
652 check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
653
654 x.mode = value
655
656
657 sig := *obj.typ.(*Signature)
658 sig.recv = nil
659 x.typ = &sig
660
661 check.addDeclDep(obj)
662
663 default:
664 unreachable()
665 }
666 }
667
668
669 x.expr = e
670 return
671
672 Error:
673 x.mode = invalid
674 x.expr = e
675 }
676
677
678
679
680
681
682 func (check *Checker) use(arg ...syntax.Expr) {
683 var x operand
684 for _, e := range arg {
685 switch n := e.(type) {
686 case nil:
687
688
689 continue
690 case *syntax.Name:
691
692 if n.Value == "_" {
693 continue
694 }
695 case *syntax.ListExpr:
696 check.use(n.ElemList...)
697 continue
698 }
699 check.rawExpr(&x, e, nil, false)
700 }
701 }
702
View as plain text