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