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