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