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