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