1
2
3
4
5
6
7 package types2
8
9 import (
10 "cmd/compile/internal/syntax"
11 "go/constant"
12 "go/token"
13 . "internal/types/errors"
14 )
15
16
17
18
19
20 func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (_ bool) {
21 argList := call.ArgList
22
23
24 bin := predeclaredFuncs[id]
25 if hasDots(call) && id != _Append {
26 check.errorf(dddErrPos(call),
27 InvalidDotDotDot,
28 invalidOp+"invalid use of ... with built-in %s", bin.name)
29 check.use(argList...)
30 return
31 }
32
33
34
35
36
37
38 if id == _Len || id == _Cap {
39 defer func(b bool) {
40 check.hasCallOrRecv = b
41 }(check.hasCallOrRecv)
42 check.hasCallOrRecv = false
43 }
44
45
46
47
48 var args []*operand
49 var nargs int
50 switch id {
51 default:
52
53 args = check.exprList(argList)
54 nargs = len(args)
55 for _, a := range args {
56 if a.mode == invalid {
57 return
58 }
59 }
60
61 if nargs > 0 {
62 *x = *args[0]
63 }
64 case _Make, _New, _Offsetof, _Trace:
65
66 nargs = len(argList)
67 }
68
69
70 {
71 msg := ""
72 if nargs < bin.nargs {
73 msg = "not enough"
74 } else if !bin.variadic && nargs > bin.nargs {
75 msg = "too many"
76 }
77 if msg != "" {
78 check.errorf(argErrPos(call), WrongArgCount, invalidOp+"%s arguments for %v (expected %d, found %d)", msg, call, bin.nargs, nargs)
79 return
80 }
81 }
82
83 switch id {
84 case _Append:
85
86
87
88
89
90 S := x.typ
91 var T Type
92 if s, _ := coreType(S).(*Slice); s != nil {
93 T = s.elem
94 } else {
95 var cause string
96 switch {
97 case x.isNil():
98 cause = "have untyped nil"
99 case isTypeParam(S):
100 if u := coreType(S); u != nil {
101 cause = check.sprintf("%s has core type %s", x, u)
102 } else {
103 cause = check.sprintf("%s has no core type", x)
104 }
105 default:
106 cause = check.sprintf("have %s", x)
107 }
108
109 check.errorf(x, InvalidAppend, "first argument to append must be a slice; %s", cause)
110 return
111 }
112
113
114
115
116 if nargs == 2 && hasDots(call) {
117 if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
118 y := args[1]
119 if t := coreString(y.typ); t != nil && isString(t) {
120 if check.recordTypes() {
121 sig := makeSig(S, S, y.typ)
122 sig.variadic = true
123 check.recordBuiltinType(call.Fun, sig)
124 }
125 x.mode = value
126 x.typ = S
127 break
128 }
129 }
130 }
131
132
133 sig := makeSig(S, S, NewSlice(T))
134 sig.variadic = true
135 check.arguments(call, sig, nil, nil, args, nil, nil)
136
137
138 x.mode = value
139 x.typ = S
140 if check.recordTypes() {
141 check.recordBuiltinType(call.Fun, sig)
142 }
143
144 case _Cap, _Len:
145
146
147 mode := invalid
148 var val constant.Value
149 switch t := arrayPtrDeref(under(x.typ)).(type) {
150 case *Basic:
151 if isString(t) && id == _Len {
152 if x.mode == constant_ {
153 mode = constant_
154 val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
155 } else {
156 mode = value
157 }
158 }
159
160 case *Array:
161 mode = value
162
163
164
165
166 if !check.hasCallOrRecv {
167 mode = constant_
168 if t.len >= 0 {
169 val = constant.MakeInt64(t.len)
170 } else {
171 val = constant.MakeUnknown()
172 }
173 }
174
175 case *Slice, *Chan:
176 mode = value
177
178 case *Map:
179 if id == _Len {
180 mode = value
181 }
182
183 case *Interface:
184 if !isTypeParam(x.typ) {
185 break
186 }
187 if t.typeSet().underIs(func(t Type) bool {
188 switch t := arrayPtrDeref(t).(type) {
189 case *Basic:
190 if isString(t) && id == _Len {
191 return true
192 }
193 case *Array, *Slice, *Chan:
194 return true
195 case *Map:
196 if id == _Len {
197 return true
198 }
199 }
200 return false
201 }) {
202 mode = value
203 }
204 }
205
206 if mode == invalid {
207
208 if isValid(under(x.typ)) {
209 code := InvalidCap
210 if id == _Len {
211 code = InvalidLen
212 }
213 check.errorf(x, code, invalidArg+"%s for built-in %s", x, bin.name)
214 }
215 return
216 }
217
218
219 if check.recordTypes() && mode != constant_ {
220 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ))
221 }
222
223 x.mode = mode
224 x.typ = Typ[Int]
225 x.val = val
226
227 case _Clear:
228
229 check.verifyVersionf(call.Fun, go1_21, "clear")
230
231 if !underIs(x.typ, func(u Type) bool {
232 switch u.(type) {
233 case *Map, *Slice:
234 return true
235 }
236 check.errorf(x, InvalidClear, invalidArg+"cannot clear %s: argument must be (or constrained by) map or slice", x)
237 return false
238 }) {
239 return
240 }
241
242 x.mode = novalue
243 if check.recordTypes() {
244 check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
245 }
246
247 case _Close:
248
249 if !underIs(x.typ, func(u Type) bool {
250 uch, _ := u.(*Chan)
251 if uch == nil {
252 check.errorf(x, InvalidClose, invalidOp+"cannot close non-channel %s", x)
253 return false
254 }
255 if uch.dir == RecvOnly {
256 check.errorf(x, InvalidClose, invalidOp+"cannot close receive-only channel %s", x)
257 return false
258 }
259 return true
260 }) {
261 return
262 }
263 x.mode = novalue
264 if check.recordTypes() {
265 check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
266 }
267
268 case _Complex:
269
270 y := args[1]
271
272
273 d := 0
274 if isUntyped(x.typ) {
275 d |= 1
276 }
277 if isUntyped(y.typ) {
278 d |= 2
279 }
280 switch d {
281 case 0:
282
283 case 1:
284
285 check.convertUntyped(x, y.typ)
286 case 2:
287
288 check.convertUntyped(y, x.typ)
289 case 3:
290
291
292
293
294
295
296
297
298 if x.mode == constant_ && y.mode == constant_ {
299 toFloat := func(x *operand) {
300 if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
301 x.typ = Typ[UntypedFloat]
302 }
303 }
304 toFloat(x)
305 toFloat(y)
306 } else {
307 check.convertUntyped(x, Typ[Float64])
308 check.convertUntyped(y, Typ[Float64])
309
310
311 }
312 }
313 if x.mode == invalid || y.mode == invalid {
314 return
315 }
316
317
318 if !Identical(x.typ, y.typ) {
319 check.errorf(x, InvalidComplex, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
320 return
321 }
322
323
324
325 f := func(typ Type) Type {
326 assert(!isTypeParam(typ))
327 if t, _ := under(typ).(*Basic); t != nil {
328 switch t.kind {
329 case Float32:
330 return Typ[Complex64]
331 case Float64:
332 return Typ[Complex128]
333 case UntypedFloat:
334 return Typ[UntypedComplex]
335 }
336 }
337 return nil
338 }
339 resTyp := check.applyTypeFunc(f, x, id)
340 if resTyp == nil {
341 check.errorf(x, InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ)
342 return
343 }
344
345
346 if x.mode == constant_ && y.mode == constant_ {
347 x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
348 } else {
349 x.mode = value
350 }
351
352 if check.recordTypes() && x.mode != constant_ {
353 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
354 }
355
356 x.typ = resTyp
357
358 case _Copy:
359
360 dst, _ := coreType(x.typ).(*Slice)
361
362 y := args[1]
363 src0 := coreString(y.typ)
364 if src0 != nil && isString(src0) {
365 src0 = NewSlice(universeByte)
366 }
367 src, _ := src0.(*Slice)
368
369 if dst == nil || src == nil {
370 check.errorf(x, InvalidCopy, invalidArg+"copy expects slice arguments; found %s and %s", x, y)
371 return
372 }
373
374 if !Identical(dst.elem, src.elem) {
375 check.errorf(x, InvalidCopy, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, y, dst.elem, src.elem)
376 return
377 }
378
379 if check.recordTypes() {
380 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
381 }
382 x.mode = value
383 x.typ = Typ[Int]
384
385 case _Delete:
386
387
388
389 map_ := x.typ
390 var key Type
391 if !underIs(map_, func(u Type) bool {
392 map_, _ := u.(*Map)
393 if map_ == nil {
394 check.errorf(x, InvalidDelete, invalidArg+"%s is not a map", x)
395 return false
396 }
397 if key != nil && !Identical(map_.key, key) {
398 check.errorf(x, InvalidDelete, invalidArg+"maps of %s must have identical key types", x)
399 return false
400 }
401 key = map_.key
402 return true
403 }) {
404 return
405 }
406
407 *x = *args[1]
408 check.assignment(x, key, "argument to delete")
409 if x.mode == invalid {
410 return
411 }
412
413 x.mode = novalue
414 if check.recordTypes() {
415 check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
416 }
417
418 case _Imag, _Real:
419
420
421
422
423 if isUntyped(x.typ) {
424 if x.mode == constant_ {
425
426
427 if isNumeric(x.typ) {
428 x.typ = Typ[UntypedComplex]
429 }
430 } else {
431
432
433
434
435 check.convertUntyped(x, Typ[Complex128])
436
437 if x.mode == invalid {
438 return
439 }
440 }
441 }
442
443
444
445 f := func(typ Type) Type {
446 assert(!isTypeParam(typ))
447 if t, _ := under(typ).(*Basic); t != nil {
448 switch t.kind {
449 case Complex64:
450 return Typ[Float32]
451 case Complex128:
452 return Typ[Float64]
453 case UntypedComplex:
454 return Typ[UntypedFloat]
455 }
456 }
457 return nil
458 }
459 resTyp := check.applyTypeFunc(f, x, id)
460 if resTyp == nil {
461 code := InvalidImag
462 if id == _Real {
463 code = InvalidReal
464 }
465 check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ)
466 return
467 }
468
469
470 if x.mode == constant_ {
471 if id == _Real {
472 x.val = constant.Real(x.val)
473 } else {
474 x.val = constant.Imag(x.val)
475 }
476 } else {
477 x.mode = value
478 }
479
480 if check.recordTypes() && x.mode != constant_ {
481 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
482 }
483
484 x.typ = resTyp
485
486 case _Make:
487
488
489
490 arg0 := argList[0]
491 T := check.varType(arg0)
492 if !isValid(T) {
493 return
494 }
495
496 var min int
497 switch coreType(T).(type) {
498 case *Slice:
499 min = 2
500 case *Map, *Chan:
501 min = 1
502 case nil:
503 check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s: no core type", arg0)
504 return
505 default:
506 check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
507 return
508 }
509 if nargs < min || min+1 < nargs {
510 check.errorf(call, WrongArgCount, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
511 return
512 }
513
514 types := []Type{T}
515 var sizes []int64
516 for _, arg := range argList[1:] {
517 typ, size := check.index(arg, -1)
518 types = append(types, typ)
519 if size >= 0 {
520 sizes = append(sizes, size)
521 }
522 }
523 if len(sizes) == 2 && sizes[0] > sizes[1] {
524 check.error(argList[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
525
526 }
527 x.mode = value
528 x.typ = T
529 if check.recordTypes() {
530 check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
531 }
532
533 case _Max, _Min:
534
535
536 check.verifyVersionf(call.Fun, go1_21, "built-in %s", bin.name)
537
538 op := token.LSS
539 if id == _Max {
540 op = token.GTR
541 }
542
543 for i, a := range args {
544 if a.mode == invalid {
545 return
546 }
547
548 if !allOrdered(a.typ) {
549 check.errorf(a, InvalidMinMaxOperand, invalidArg+"%s cannot be ordered", a)
550 return
551 }
552
553
554 if i > 0 {
555 check.matchTypes(x, a)
556 if x.mode == invalid {
557 return
558 }
559
560 if !Identical(x.typ, a.typ) {
561 check.errorf(a, MismatchedTypes, invalidArg+"mismatched types %s (previous argument) and %s (type of %s)", x.typ, a.typ, a.expr)
562 return
563 }
564
565 if x.mode == constant_ && a.mode == constant_ {
566 if constant.Compare(a.val, op, x.val) {
567 *x = *a
568 }
569 } else {
570 x.mode = value
571 }
572 }
573 }
574
575
576 if x.mode != constant_ {
577 x.mode = value
578
579 check.assignment(x, &emptyInterface, "argument to built-in "+bin.name)
580 if x.mode == invalid {
581 return
582 }
583 }
584
585
586 for _, a := range args {
587 check.updateExprType(a.expr, x.typ, true)
588 }
589
590 if check.recordTypes() && x.mode != constant_ {
591 types := make([]Type, nargs)
592 for i := range types {
593 types[i] = x.typ
594 }
595 check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
596 }
597
598 case _New:
599
600
601 T := check.varType(argList[0])
602 if !isValid(T) {
603 return
604 }
605
606 x.mode = value
607 x.typ = &Pointer{base: T}
608 if check.recordTypes() {
609 check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
610 }
611
612 case _Panic:
613
614
615
616 if check.sig != nil && check.sig.results.Len() > 0 {
617
618 p := check.isPanic
619 if p == nil {
620
621 p = make(map[*syntax.CallExpr]bool)
622 check.isPanic = p
623 }
624 p[call] = true
625 }
626
627 check.assignment(x, &emptyInterface, "argument to panic")
628 if x.mode == invalid {
629 return
630 }
631
632 x.mode = novalue
633 if check.recordTypes() {
634 check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
635 }
636
637 case _Print, _Println:
638
639
640 var params []Type
641 if nargs > 0 {
642 params = make([]Type, nargs)
643 for i, a := range args {
644 check.assignment(a, nil, "argument to built-in"+predeclaredFuncs[id].name)
645 if a.mode == invalid {
646 return
647 }
648 params[i] = a.typ
649 }
650 }
651
652 x.mode = novalue
653 if check.recordTypes() {
654 check.recordBuiltinType(call.Fun, makeSig(nil, params...))
655 }
656
657 case _Recover:
658
659 x.mode = value
660 x.typ = &emptyInterface
661 if check.recordTypes() {
662 check.recordBuiltinType(call.Fun, makeSig(x.typ))
663 }
664
665 case _Add:
666
667 check.verifyVersionf(call.Fun, go1_17, "unsafe.Add")
668
669 check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
670 if x.mode == invalid {
671 return
672 }
673
674 y := args[1]
675 if !check.isValidIndex(y, InvalidUnsafeAdd, "length", true) {
676 return
677 }
678
679 x.mode = value
680 x.typ = Typ[UnsafePointer]
681 if check.recordTypes() {
682 check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
683 }
684
685 case _Alignof:
686
687 check.assignment(x, nil, "argument to unsafe.Alignof")
688 if x.mode == invalid {
689 return
690 }
691
692 if hasVarSize(x.typ, nil) {
693 x.mode = value
694 if check.recordTypes() {
695 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
696 }
697 } else {
698 x.mode = constant_
699 x.val = constant.MakeInt64(check.conf.alignof(x.typ))
700
701 }
702 x.typ = Typ[Uintptr]
703
704 case _Offsetof:
705
706
707 arg0 := argList[0]
708 selx, _ := syntax.Unparen(arg0).(*syntax.SelectorExpr)
709 if selx == nil {
710 check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
711 check.use(arg0)
712 return
713 }
714
715 check.expr(nil, x, selx.X)
716 if x.mode == invalid {
717 return
718 }
719
720 base := derefStructPtr(x.typ)
721 sel := selx.Sel.Value
722 obj, index, indirect := lookupFieldOrMethod(base, false, check.pkg, sel, false)
723 switch obj.(type) {
724 case nil:
725 check.errorf(x, MissingFieldOrMethod, invalidArg+"%s has no single field %s", base, sel)
726 return
727 case *Func:
728
729
730
731
732 check.errorf(arg0, InvalidOffsetof, invalidArg+"%s is a method value", arg0)
733 return
734 }
735 if indirect {
736 check.errorf(x, InvalidOffsetof, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
737 return
738 }
739
740
741 check.recordSelection(selx, FieldVal, base, obj, index, false)
742
743
744 {
745 mode := value
746 if x.mode == variable || indirect {
747 mode = variable
748 }
749 check.record(&operand{mode, selx, obj.Type(), nil, 0})
750 }
751
752
753
754
755
756 if hasVarSize(base, nil) {
757 x.mode = value
758 if check.recordTypes() {
759 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
760 }
761 } else {
762 offs := check.conf.offsetof(base, index)
763 if offs < 0 {
764 check.errorf(x, TypeTooLarge, "%s is too large", x)
765 return
766 }
767 x.mode = constant_
768 x.val = constant.MakeInt64(offs)
769
770 }
771 x.typ = Typ[Uintptr]
772
773 case _Sizeof:
774
775 check.assignment(x, nil, "argument to unsafe.Sizeof")
776 if x.mode == invalid {
777 return
778 }
779
780 if hasVarSize(x.typ, nil) {
781 x.mode = value
782 if check.recordTypes() {
783 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
784 }
785 } else {
786 size := check.conf.sizeof(x.typ)
787 if size < 0 {
788 check.errorf(x, TypeTooLarge, "%s is too large", x)
789 return
790 }
791 x.mode = constant_
792 x.val = constant.MakeInt64(size)
793
794 }
795 x.typ = Typ[Uintptr]
796
797 case _Slice:
798
799 check.verifyVersionf(call.Fun, go1_17, "unsafe.Slice")
800
801 ptr, _ := coreType(x.typ).(*Pointer)
802 if ptr == nil {
803 check.errorf(x, InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
804 return
805 }
806
807 y := args[1]
808 if !check.isValidIndex(y, InvalidUnsafeSlice, "length", false) {
809 return
810 }
811
812 x.mode = value
813 x.typ = NewSlice(ptr.base)
814 if check.recordTypes() {
815 check.recordBuiltinType(call.Fun, makeSig(x.typ, ptr, y.typ))
816 }
817
818 case _SliceData:
819
820 check.verifyVersionf(call.Fun, go1_20, "unsafe.SliceData")
821
822 slice, _ := coreType(x.typ).(*Slice)
823 if slice == nil {
824 check.errorf(x, InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
825 return
826 }
827
828 x.mode = value
829 x.typ = NewPointer(slice.elem)
830 if check.recordTypes() {
831 check.recordBuiltinType(call.Fun, makeSig(x.typ, slice))
832 }
833
834 case _String:
835
836 check.verifyVersionf(call.Fun, go1_20, "unsafe.String")
837
838 check.assignment(x, NewPointer(universeByte), "argument to unsafe.String")
839 if x.mode == invalid {
840 return
841 }
842
843 y := args[1]
844 if !check.isValidIndex(y, InvalidUnsafeString, "length", false) {
845 return
846 }
847
848 x.mode = value
849 x.typ = Typ[String]
850 if check.recordTypes() {
851 check.recordBuiltinType(call.Fun, makeSig(x.typ, NewPointer(universeByte), y.typ))
852 }
853
854 case _StringData:
855
856 check.verifyVersionf(call.Fun, go1_20, "unsafe.StringData")
857
858 check.assignment(x, Typ[String], "argument to unsafe.StringData")
859 if x.mode == invalid {
860 return
861 }
862
863 x.mode = value
864 x.typ = NewPointer(universeByte)
865 if check.recordTypes() {
866 check.recordBuiltinType(call.Fun, makeSig(x.typ, Typ[String]))
867 }
868
869 case _Assert:
870
871
872
873 if x.mode != constant_ || !isBoolean(x.typ) {
874 check.errorf(x, Test, invalidArg+"%s is not a boolean constant", x)
875 return
876 }
877 if x.val.Kind() != constant.Bool {
878 check.errorf(x, Test, "internal error: value of %s should be a boolean constant", x)
879 return
880 }
881 if !constant.BoolVal(x.val) {
882 check.errorf(call, Test, "%v failed", call)
883
884 }
885
886
887 case _Trace:
888
889
890
891
892
893 if nargs == 0 {
894 check.dump("%v: trace() without arguments", atPos(call))
895 x.mode = novalue
896 break
897 }
898 var t operand
899 x1 := x
900 for _, arg := range argList {
901 check.rawExpr(nil, x1, arg, nil, false)
902 check.dump("%v: %s", atPos(x1), x1)
903 x1 = &t
904 }
905 if x.mode == invalid {
906 return
907 }
908
909
910 default:
911 panic("unreachable")
912 }
913
914 assert(x.mode != invalid)
915 return true
916 }
917
918
919
920
921 func hasVarSize(t Type, seen map[*Named]bool) (varSized bool) {
922
923
924
925 if named := asNamed(t); named != nil {
926 if v, ok := seen[named]; ok {
927 return v
928 }
929 if seen == nil {
930 seen = make(map[*Named]bool)
931 }
932 seen[named] = true
933 defer func() {
934 seen[named] = varSized
935 }()
936 }
937
938 switch u := under(t).(type) {
939 case *Array:
940 return hasVarSize(u.elem, seen)
941 case *Struct:
942 for _, f := range u.fields {
943 if hasVarSize(f.typ, seen) {
944 return true
945 }
946 }
947 case *Interface:
948 return isTypeParam(t)
949 case *Named, *Union:
950 panic("unreachable")
951 }
952 return false
953 }
954
955
956
957
958
959
960
961
962 func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
963 if tp, _ := Unalias(x.typ).(*TypeParam); tp != nil {
964
965
966 var terms []*Term
967 if !tp.is(func(t *term) bool {
968 if t == nil {
969 return false
970 }
971 if r := f(t.typ); r != nil {
972 terms = append(terms, NewTerm(t.tilde, r))
973 return true
974 }
975 return false
976 }) {
977 return nil
978 }
979
980
981
982
983
984 var code Code
985 switch id {
986 case _Real:
987 code = InvalidReal
988 case _Imag:
989 code = InvalidImag
990 case _Complex:
991 code = InvalidComplex
992 default:
993 panic("unreachable")
994 }
995 check.softErrorf(x, code, "%s not supported as argument to built-in %s for go1.18 (see go.dev/issue/50937)", x, predeclaredFuncs[id].name)
996
997
998
999
1000 tpar := NewTypeName(nopos, check.pkg, tp.obj.name, nil)
1001 ptyp := check.newTypeParam(tpar, NewInterfaceType(nil, []Type{NewUnion(terms)}))
1002 ptyp.index = tp.index
1003
1004 return ptyp
1005 }
1006
1007 return f(x.typ)
1008 }
1009
1010
1011
1012 func makeSig(res Type, args ...Type) *Signature {
1013 list := make([]*Var, len(args))
1014 for i, param := range args {
1015 list[i] = NewVar(nopos, nil, "", Default(param))
1016 }
1017 params := NewTuple(list...)
1018 var result *Tuple
1019 if res != nil {
1020 assert(!isUntyped(res))
1021 result = NewTuple(NewVar(nopos, nil, "", res))
1022 }
1023 return &Signature{params: params, results: result}
1024 }
1025
1026
1027
1028 func arrayPtrDeref(typ Type) Type {
1029 if p, ok := Unalias(typ).(*Pointer); ok {
1030 if a, _ := under(p.base).(*Array); a != nil {
1031 return a
1032 }
1033 }
1034 return typ
1035 }
1036
View as plain text