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
91
92
93
94
95
96 var sig *Signature
97 if nargs == 2 && hasDots(call) {
98 if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
99 y := args[1]
100 hasString := false
101 for _, u := range typeset(y.typ) {
102 if s, _ := u.(*Slice); s != nil && Identical(s.elem, universeByte) {
103
104 } else if isString(u) {
105
106 hasString = true
107 } else {
108 y = nil
109 break
110 }
111 }
112 if y != nil && hasString {
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 for _, u := range typeset(y.typ) {
372 if s, _ := u.(*Slice); s != nil && Identical(s.elem, universeByte) {
373
374 } else if isString(u) {
375
376 } else {
377 special = false
378 break
379 }
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 arg := argList[0]
642 check.exprOrType(x, arg, true)
643 var T Type
644 switch x.mode {
645 case builtin:
646 check.errorf(x, UncalledBuiltin, "%s must be called", x)
647 x.mode = invalid
648 case typexpr:
649
650 T = x.typ
651 if !isValid(T) {
652 return
653 }
654 default:
655
656 check.verifyVersionf(call.Fun, go1_26, "new(expr)")
657 T = Default(x.typ)
658 if T != x.typ {
659
660 check.assignment(x, T, "argument to new")
661 }
662 check.validVarType(arg, T)
663 }
664
665 x.mode = value
666 x.typ = &Pointer{base: T}
667 if check.recordTypes() {
668 check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
669 }
670
671 case _Panic:
672
673
674
675 if check.sig != nil && check.sig.results.Len() > 0 {
676
677 p := check.isPanic
678 if p == nil {
679
680 p = make(map[*syntax.CallExpr]bool)
681 check.isPanic = p
682 }
683 p[call] = true
684 }
685
686 check.assignment(x, &emptyInterface, "argument to panic")
687 if x.mode == invalid {
688 return
689 }
690
691 x.mode = novalue
692 if check.recordTypes() {
693 check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
694 }
695
696 case _Print, _Println:
697
698
699 var params []Type
700 if nargs > 0 {
701 params = make([]Type, nargs)
702 for i, a := range args {
703 check.assignment(a, nil, "argument to built-in "+predeclaredFuncs[id].name)
704 if a.mode == invalid {
705 return
706 }
707 params[i] = a.typ
708 }
709 }
710
711 x.mode = novalue
712 if check.recordTypes() {
713 check.recordBuiltinType(call.Fun, makeSig(nil, params...))
714 }
715
716 case _Recover:
717
718 x.mode = value
719 x.typ = &emptyInterface
720 if check.recordTypes() {
721 check.recordBuiltinType(call.Fun, makeSig(x.typ))
722 }
723
724 case _Add:
725
726 check.verifyVersionf(call.Fun, go1_17, "unsafe.Add")
727
728 check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
729 if x.mode == invalid {
730 return
731 }
732
733 y := args[1]
734 if !check.isValidIndex(y, InvalidUnsafeAdd, "length", true) {
735 return
736 }
737
738 x.mode = value
739 x.typ = Typ[UnsafePointer]
740 if check.recordTypes() {
741 check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
742 }
743
744 case _Alignof:
745
746 check.assignment(x, nil, "argument to unsafe.Alignof")
747 if x.mode == invalid {
748 return
749 }
750
751 if hasVarSize(x.typ, nil) {
752 x.mode = value
753 if check.recordTypes() {
754 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
755 }
756 } else {
757 x.mode = constant_
758 x.val = constant.MakeInt64(check.conf.alignof(x.typ))
759
760 }
761 x.typ = Typ[Uintptr]
762
763 case _Offsetof:
764
765
766 arg0 := argList[0]
767 selx, _ := syntax.Unparen(arg0).(*syntax.SelectorExpr)
768 if selx == nil {
769 check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
770 check.use(arg0)
771 return
772 }
773
774 check.expr(nil, x, selx.X)
775 if x.mode == invalid {
776 return
777 }
778
779 base := derefStructPtr(x.typ)
780 sel := selx.Sel.Value
781 obj, index, indirect := lookupFieldOrMethod(base, false, check.pkg, sel, false)
782 switch obj.(type) {
783 case nil:
784 check.errorf(x, MissingFieldOrMethod, invalidArg+"%s has no single field %s", base, sel)
785 return
786 case *Func:
787
788
789
790
791 check.errorf(arg0, InvalidOffsetof, invalidArg+"%s is a method value", arg0)
792 return
793 }
794 if indirect {
795 check.errorf(x, InvalidOffsetof, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
796 return
797 }
798
799
800 check.recordSelection(selx, FieldVal, base, obj, index, false)
801
802
803 {
804 mode := value
805 if x.mode == variable || indirect {
806 mode = variable
807 }
808 check.record(&operand{mode, selx, obj.Type(), nil, 0})
809 }
810
811
812
813
814
815 if hasVarSize(base, nil) {
816 x.mode = value
817 if check.recordTypes() {
818 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
819 }
820 } else {
821 offs := check.conf.offsetof(base, index)
822 if offs < 0 {
823 check.errorf(x, TypeTooLarge, "%s is too large", x)
824 return
825 }
826 x.mode = constant_
827 x.val = constant.MakeInt64(offs)
828
829 }
830 x.typ = Typ[Uintptr]
831
832 case _Sizeof:
833
834 check.assignment(x, nil, "argument to unsafe.Sizeof")
835 if x.mode == invalid {
836 return
837 }
838
839 if hasVarSize(x.typ, nil) {
840 x.mode = value
841 if check.recordTypes() {
842 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
843 }
844 } else {
845 size := check.conf.sizeof(x.typ)
846 if size < 0 {
847 check.errorf(x, TypeTooLarge, "%s is too large", x)
848 return
849 }
850 x.mode = constant_
851 x.val = constant.MakeInt64(size)
852
853 }
854 x.typ = Typ[Uintptr]
855
856 case _Slice:
857
858 check.verifyVersionf(call.Fun, go1_17, "unsafe.Slice")
859
860 u, _ := commonUnder(x.typ, nil)
861 ptr, _ := u.(*Pointer)
862 if ptr == nil {
863 check.errorf(x, InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
864 return
865 }
866
867 y := args[1]
868 if !check.isValidIndex(y, InvalidUnsafeSlice, "length", false) {
869 return
870 }
871
872 x.mode = value
873 x.typ = NewSlice(ptr.base)
874 if check.recordTypes() {
875 check.recordBuiltinType(call.Fun, makeSig(x.typ, ptr, y.typ))
876 }
877
878 case _SliceData:
879
880 check.verifyVersionf(call.Fun, go1_20, "unsafe.SliceData")
881
882 u, _ := commonUnder(x.typ, nil)
883 slice, _ := u.(*Slice)
884 if slice == nil {
885 check.errorf(x, InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
886 return
887 }
888
889 x.mode = value
890 x.typ = NewPointer(slice.elem)
891 if check.recordTypes() {
892 check.recordBuiltinType(call.Fun, makeSig(x.typ, slice))
893 }
894
895 case _String:
896
897 check.verifyVersionf(call.Fun, go1_20, "unsafe.String")
898
899 check.assignment(x, NewPointer(universeByte), "argument to unsafe.String")
900 if x.mode == invalid {
901 return
902 }
903
904 y := args[1]
905 if !check.isValidIndex(y, InvalidUnsafeString, "length", false) {
906 return
907 }
908
909 x.mode = value
910 x.typ = Typ[String]
911 if check.recordTypes() {
912 check.recordBuiltinType(call.Fun, makeSig(x.typ, NewPointer(universeByte), y.typ))
913 }
914
915 case _StringData:
916
917 check.verifyVersionf(call.Fun, go1_20, "unsafe.StringData")
918
919 check.assignment(x, Typ[String], "argument to unsafe.StringData")
920 if x.mode == invalid {
921 return
922 }
923
924 x.mode = value
925 x.typ = NewPointer(universeByte)
926 if check.recordTypes() {
927 check.recordBuiltinType(call.Fun, makeSig(x.typ, Typ[String]))
928 }
929
930 case _Assert:
931
932
933
934 if x.mode != constant_ || !isBoolean(x.typ) {
935 check.errorf(x, Test, invalidArg+"%s is not a boolean constant", x)
936 return
937 }
938 if x.val.Kind() != constant.Bool {
939 check.errorf(x, Test, "internal error: value of %s should be a boolean constant", x)
940 return
941 }
942 if !constant.BoolVal(x.val) {
943 check.errorf(call, Test, "%v failed", call)
944
945 }
946
947
948 case _Trace:
949
950
951
952
953
954 if nargs == 0 {
955 check.dump("%v: trace() without arguments", atPos(call))
956 x.mode = novalue
957 break
958 }
959 var t operand
960 x1 := x
961 for _, arg := range argList {
962 check.rawExpr(nil, x1, arg, nil, false)
963 check.dump("%v: %s", atPos(x1), x1)
964 x1 = &t
965 }
966 if x.mode == invalid {
967 return
968 }
969
970
971 default:
972 panic("unreachable")
973 }
974
975 assert(x.mode != invalid)
976 return true
977 }
978
979
980
981 func sliceElem(x *operand) (Type, *typeError) {
982 var E Type
983 for _, u := range typeset(x.typ) {
984 s, _ := u.(*Slice)
985 if s == nil {
986 if x.isNil() {
987
988
989 return nil, typeErrorf("argument must be a slice; have untyped nil")
990 } else {
991 return nil, typeErrorf("argument must be a slice; have %s", x)
992 }
993 }
994 if E == nil {
995 E = s.elem
996 } else if !Identical(E, s.elem) {
997 return nil, typeErrorf("mismatched slice element types %s and %s in %s", E, s.elem, x)
998 }
999 }
1000 return E, nil
1001 }
1002
1003
1004
1005
1006 func hasVarSize(t Type, seen map[*Named]bool) (varSized bool) {
1007
1008
1009
1010 if named := asNamed(t); named != nil {
1011 if v, ok := seen[named]; ok {
1012 return v
1013 }
1014 if seen == nil {
1015 seen = make(map[*Named]bool)
1016 }
1017 seen[named] = true
1018 defer func() {
1019 seen[named] = varSized
1020 }()
1021 }
1022
1023 switch u := under(t).(type) {
1024 case *Array:
1025 return hasVarSize(u.elem, seen)
1026 case *Struct:
1027 for _, f := range u.fields {
1028 if hasVarSize(f.typ, seen) {
1029 return true
1030 }
1031 }
1032 case *Interface:
1033 return isTypeParam(t)
1034 case *Named, *Union:
1035 panic("unreachable")
1036 }
1037 return false
1038 }
1039
1040
1041
1042
1043
1044
1045
1046
1047 func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
1048 if tp, _ := Unalias(x.typ).(*TypeParam); tp != nil {
1049
1050
1051 var terms []*Term
1052 if !tp.is(func(t *term) bool {
1053 if t == nil {
1054 return false
1055 }
1056 if r := f(t.typ); r != nil {
1057 terms = append(terms, NewTerm(t.tilde, r))
1058 return true
1059 }
1060 return false
1061 }) {
1062 return nil
1063 }
1064
1065
1066
1067
1068
1069 var code Code
1070 switch id {
1071 case _Real:
1072 code = InvalidReal
1073 case _Imag:
1074 code = InvalidImag
1075 case _Complex:
1076 code = InvalidComplex
1077 default:
1078 panic("unreachable")
1079 }
1080 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)
1081
1082
1083
1084
1085 tpar := NewTypeName(nopos, check.pkg, tp.obj.name, nil)
1086 ptyp := check.newTypeParam(tpar, NewInterfaceType(nil, []Type{NewUnion(terms)}))
1087 ptyp.index = tp.index
1088
1089 return ptyp
1090 }
1091
1092 return f(x.typ)
1093 }
1094
1095
1096
1097 func makeSig(res Type, args ...Type) *Signature {
1098 list := make([]*Var, len(args))
1099 for i, param := range args {
1100 list[i] = NewParam(nopos, nil, "", Default(param))
1101 }
1102 params := NewTuple(list...)
1103 var result *Tuple
1104 if res != nil {
1105 assert(!isUntyped(res))
1106 result = NewTuple(newVar(ResultVar, nopos, nil, "", res))
1107 }
1108 return &Signature{params: params, results: result}
1109 }
1110
1111
1112
1113 func arrayPtrDeref(typ Type) Type {
1114 if p, ok := Unalias(typ).(*Pointer); ok {
1115 if a, _ := under(p.base).(*Array); a != nil {
1116 return a
1117 }
1118 }
1119 return typ
1120 }
1121
View as plain text