Source file
src/go/types/builtins.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "go/ast"
11 "go/constant"
12 "go/token"
13 )
14
15
16
17
18
19 func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
20
21 bin := predeclaredFuncs[id]
22 if call.Ellipsis.IsValid() && id != _Append {
23 check.invalidOp(atPos(call.Ellipsis),
24 _InvalidDotDotDot,
25 "invalid use of ... with built-in %s", bin.name)
26 check.use(call.Args...)
27 return
28 }
29
30
31
32
33
34
35 if id == _Len || id == _Cap {
36 defer func(b bool) {
37 check.hasCallOrRecv = b
38 }(check.hasCallOrRecv)
39 check.hasCallOrRecv = false
40 }
41
42
43 var arg func(*operand, int)
44 nargs := len(call.Args)
45 switch id {
46 default:
47
48 xlist, _ := check.exprList(call.Args, false)
49 arg = func(x *operand, i int) { *x = *xlist[i] }
50 nargs = len(xlist)
51
52 if nargs > 0 {
53 arg(x, 0)
54 if x.mode == invalid {
55 return
56 }
57 }
58 case _Make, _New, _Offsetof, _Trace:
59
60 }
61
62
63 {
64 msg := ""
65 if nargs < bin.nargs {
66 msg = "not enough"
67 } else if !bin.variadic && nargs > bin.nargs {
68 msg = "too many"
69 }
70 if msg != "" {
71 check.invalidOp(inNode(call, call.Rparen), _WrongArgCount, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
72 return
73 }
74 }
75
76 switch id {
77 case _Append:
78
79
80
81
82
83 S := x.typ
84 var T Type
85 if s, _ := coreType(S).(*Slice); s != nil {
86 T = s.elem
87 } else {
88 var cause string
89 switch {
90 case x.isNil():
91 cause = "have untyped nil"
92 case isTypeParam(S):
93 if u := coreType(S); u != nil {
94 cause = check.sprintf("%s has core type %s", x, u)
95 } else {
96 cause = check.sprintf("%s has no core type", x)
97 }
98 default:
99 cause = check.sprintf("have %s", x)
100 }
101
102 check.errorf(x, _InvalidAppend, "first argument to append must be a slice; %s", cause)
103 return
104 }
105
106
107 alist := []operand{*x}
108
109
110
111
112 if nargs == 2 && call.Ellipsis.IsValid() {
113 if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
114 arg(x, 1)
115 if x.mode == invalid {
116 return
117 }
118 if t := coreString(x.typ); t != nil && isString(t) {
119 if check.Types != nil {
120 sig := makeSig(S, S, x.typ)
121 sig.variadic = true
122 check.recordBuiltinType(call.Fun, sig)
123 }
124 x.mode = value
125 x.typ = S
126 break
127 }
128 alist = append(alist, *x)
129
130 }
131 }
132
133
134 sig := makeSig(S, S, NewSlice(T))
135 sig.variadic = true
136 var xlist []*operand
137
138 for i := range alist {
139 xlist = append(xlist, &alist[i])
140 }
141 for i := len(alist); i < nargs; i++ {
142 var x operand
143 arg(&x, i)
144 xlist = append(xlist, &x)
145 }
146 check.arguments(call, sig, nil, xlist, nil)
147
148
149 x.mode = value
150 x.typ = S
151 if check.Types != nil {
152 check.recordBuiltinType(call.Fun, sig)
153 }
154
155 case _Cap, _Len:
156
157
158 mode := invalid
159 var val constant.Value
160 switch t := arrayPtrDeref(under(x.typ)).(type) {
161 case *Basic:
162 if isString(t) && id == _Len {
163 if x.mode == constant_ {
164 mode = constant_
165 val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
166 } else {
167 mode = value
168 }
169 }
170
171 case *Array:
172 mode = value
173
174
175
176
177 if !check.hasCallOrRecv {
178 mode = constant_
179 if t.len >= 0 {
180 val = constant.MakeInt64(t.len)
181 } else {
182 val = constant.MakeUnknown()
183 }
184 }
185
186 case *Slice, *Chan:
187 mode = value
188
189 case *Map:
190 if id == _Len {
191 mode = value
192 }
193
194 case *Interface:
195 if !isTypeParam(x.typ) {
196 break
197 }
198 if t.typeSet().underIs(func(t Type) bool {
199 switch t := arrayPtrDeref(t).(type) {
200 case *Basic:
201 if isString(t) && id == _Len {
202 return true
203 }
204 case *Array, *Slice, *Chan:
205 return true
206 case *Map:
207 if id == _Len {
208 return true
209 }
210 }
211 return false
212 }) {
213 mode = value
214 }
215 }
216
217 if mode == invalid && under(x.typ) != Typ[Invalid] {
218 code := _InvalidCap
219 if id == _Len {
220 code = _InvalidLen
221 }
222 check.invalidArg(x, code, "%s for %s", x, bin.name)
223 return
224 }
225
226
227 if check.Types != nil && mode != constant_ {
228 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ))
229 }
230
231 x.mode = mode
232 x.typ = Typ[Int]
233 x.val = val
234
235 case _Close:
236
237 if !underIs(x.typ, func(u Type) bool {
238 uch, _ := u.(*Chan)
239 if uch == nil {
240 check.invalidOp(x, _InvalidClose, "cannot close non-channel %s", x)
241 return false
242 }
243 if uch.dir == RecvOnly {
244 check.invalidOp(x, _InvalidClose, "cannot close receive-only channel %s", x)
245 return false
246 }
247 return true
248 }) {
249 return
250 }
251 x.mode = novalue
252 if check.Types != nil {
253 check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
254 }
255
256 case _Complex:
257
258 var y operand
259 arg(&y, 1)
260 if y.mode == invalid {
261 return
262 }
263
264
265 d := 0
266 if isUntyped(x.typ) {
267 d |= 1
268 }
269 if isUntyped(y.typ) {
270 d |= 2
271 }
272 switch d {
273 case 0:
274
275 case 1:
276
277 check.convertUntyped(x, y.typ)
278 case 2:
279
280 check.convertUntyped(&y, x.typ)
281 case 3:
282
283
284
285
286
287
288
289
290 if x.mode == constant_ && y.mode == constant_ {
291 toFloat := func(x *operand) {
292 if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
293 x.typ = Typ[UntypedFloat]
294 }
295 }
296 toFloat(x)
297 toFloat(&y)
298 } else {
299 check.convertUntyped(x, Typ[Float64])
300 check.convertUntyped(&y, Typ[Float64])
301
302
303 }
304 }
305 if x.mode == invalid || y.mode == invalid {
306 return
307 }
308
309
310 if !Identical(x.typ, y.typ) {
311 check.invalidArg(x, _InvalidComplex, "mismatched types %s and %s", x.typ, y.typ)
312 return
313 }
314
315
316
317 f := func(typ Type) Type {
318 assert(!isTypeParam(typ))
319 if t, _ := under(typ).(*Basic); t != nil {
320 switch t.kind {
321 case Float32:
322 return Typ[Complex64]
323 case Float64:
324 return Typ[Complex128]
325 case UntypedFloat:
326 return Typ[UntypedComplex]
327 }
328 }
329 return nil
330 }
331 resTyp := check.applyTypeFunc(f, x, id)
332 if resTyp == nil {
333 check.invalidArg(x, _InvalidComplex, "arguments have type %s, expected floating-point", x.typ)
334 return
335 }
336
337
338 if x.mode == constant_ && y.mode == constant_ {
339 x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
340 } else {
341 x.mode = value
342 }
343
344 if check.Types != nil && x.mode != constant_ {
345 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
346 }
347
348 x.typ = resTyp
349
350 case _Copy:
351
352 dst, _ := coreType(x.typ).(*Slice)
353
354 var y operand
355 arg(&y, 1)
356 if y.mode == invalid {
357 return
358 }
359 src0 := coreString(y.typ)
360 if src0 != nil && isString(src0) {
361 src0 = NewSlice(universeByte)
362 }
363 src, _ := src0.(*Slice)
364
365 if dst == nil || src == nil {
366 check.invalidArg(x, _InvalidCopy, "copy expects slice arguments; found %s and %s", x, &y)
367 return
368 }
369
370 if !Identical(dst.elem, src.elem) {
371 check.errorf(x, _InvalidCopy, "arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
372 return
373 }
374
375 if check.Types != nil {
376 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
377 }
378 x.mode = value
379 x.typ = Typ[Int]
380
381 case _Delete:
382
383
384
385 map_ := x.typ
386 var key Type
387 if !underIs(map_, func(u Type) bool {
388 map_, _ := u.(*Map)
389 if map_ == nil {
390 check.invalidArg(x, _InvalidDelete, "%s is not a map", x)
391 return false
392 }
393 if key != nil && !Identical(map_.key, key) {
394 check.invalidArg(x, _InvalidDelete, "maps of %s must have identical key types", x)
395 return false
396 }
397 key = map_.key
398 return true
399 }) {
400 return
401 }
402
403 arg(x, 1)
404 if x.mode == invalid {
405 return
406 }
407
408 check.assignment(x, key, "argument to delete")
409 if x.mode == invalid {
410 return
411 }
412
413 x.mode = novalue
414 if check.Types != nil {
415 check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
416 }
417
418 case _Imag, _Real:
419
420
421
422
423 if isUntyped(x.typ) {
424 if x.mode == constant_ {
425
426
427 if isNumeric(x.typ) {
428 x.typ = Typ[UntypedComplex]
429 }
430 } else {
431
432
433
434
435 check.convertUntyped(x, Typ[Complex128])
436
437 if x.mode == invalid {
438 return
439 }
440 }
441 }
442
443
444
445 f := func(typ Type) Type {
446 assert(!isTypeParam(typ))
447 if t, _ := under(typ).(*Basic); t != nil {
448 switch t.kind {
449 case Complex64:
450 return Typ[Float32]
451 case Complex128:
452 return Typ[Float64]
453 case UntypedComplex:
454 return Typ[UntypedFloat]
455 }
456 }
457 return nil
458 }
459 resTyp := check.applyTypeFunc(f, x, id)
460 if resTyp == nil {
461 code := _InvalidImag
462 if id == _Real {
463 code = _InvalidReal
464 }
465 check.invalidArg(x, code, "argument has type %s, expected complex type", x.typ)
466 return
467 }
468
469
470 if x.mode == constant_ {
471 if id == _Real {
472 x.val = constant.Real(x.val)
473 } else {
474 x.val = constant.Imag(x.val)
475 }
476 } else {
477 x.mode = value
478 }
479
480 if check.Types != nil && x.mode != constant_ {
481 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
482 }
483
484 x.typ = resTyp
485
486 case _Make:
487
488
489
490 arg0 := call.Args[0]
491 T := check.varType(arg0)
492 if T == Typ[Invalid] {
493 return
494 }
495
496 var min int
497 switch coreType(T).(type) {
498 case *Slice:
499 min = 2
500 case *Map, *Chan:
501 min = 1
502 case nil:
503 check.errorf(arg0, _InvalidMake, "cannot make %s: no core type", arg0)
504 return
505 default:
506 check.invalidArg(arg0, _InvalidMake, "cannot make %s; type must be slice, map, or channel", arg0)
507 return
508 }
509 if nargs < min || min+1 < nargs {
510 check.invalidOp(call, _WrongArgCount, "%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
511 return
512 }
513
514 types := []Type{T}
515 var sizes []int64
516 for _, arg := range call.Args[1:] {
517 typ, size := check.index(arg, -1)
518 types = append(types, typ)
519 if size >= 0 {
520 sizes = append(sizes, size)
521 }
522 }
523 if len(sizes) == 2 && sizes[0] > sizes[1] {
524 check.invalidArg(call.Args[1], _SwappedMakeArgs, "length and capacity swapped")
525
526 }
527 x.mode = value
528 x.typ = T
529 if check.Types != nil {
530 check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
531 }
532
533 case _New:
534
535
536 T := check.varType(call.Args[0])
537 if T == Typ[Invalid] {
538 return
539 }
540
541 x.mode = value
542 x.typ = &Pointer{base: T}
543 if check.Types != nil {
544 check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
545 }
546
547 case _Panic:
548
549
550
551 if check.sig != nil && check.sig.results.Len() > 0 {
552
553 p := check.isPanic
554 if p == nil {
555
556 p = make(map[*ast.CallExpr]bool)
557 check.isPanic = p
558 }
559 p[call] = true
560 }
561
562 check.assignment(x, &emptyInterface, "argument to panic")
563 if x.mode == invalid {
564 return
565 }
566
567 x.mode = novalue
568 if check.Types != nil {
569 check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
570 }
571
572 case _Print, _Println:
573
574
575 var params []Type
576 if nargs > 0 {
577 params = make([]Type, nargs)
578 for i := 0; i < nargs; i++ {
579 if i > 0 {
580 arg(x, i)
581 }
582 check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
583 if x.mode == invalid {
584
585 return
586 }
587 params[i] = x.typ
588 }
589 }
590
591 x.mode = novalue
592 if check.Types != nil {
593 check.recordBuiltinType(call.Fun, makeSig(nil, params...))
594 }
595
596 case _Recover:
597
598 x.mode = value
599 x.typ = &emptyInterface
600 if check.Types != nil {
601 check.recordBuiltinType(call.Fun, makeSig(x.typ))
602 }
603
604 case _Add:
605
606 if !check.allowVersion(check.pkg, 1, 17) {
607 check.errorf(call.Fun, _InvalidUnsafeAdd, "unsafe.Add requires go1.17 or later")
608 return
609 }
610
611 check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
612 if x.mode == invalid {
613 return
614 }
615
616 var y operand
617 arg(&y, 1)
618 if !check.isValidIndex(&y, _InvalidUnsafeAdd, "length", true) {
619 return
620 }
621
622 x.mode = value
623 x.typ = Typ[UnsafePointer]
624 if check.Types != nil {
625 check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
626 }
627
628 case _Alignof:
629
630 check.assignment(x, nil, "argument to unsafe.Alignof")
631 if x.mode == invalid {
632 return
633 }
634
635 if hasVarSize(x.typ, nil) {
636 x.mode = value
637 if check.Types != nil {
638 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
639 }
640 } else {
641 x.mode = constant_
642 x.val = constant.MakeInt64(check.conf.alignof(x.typ))
643
644 }
645 x.typ = Typ[Uintptr]
646
647 case _Offsetof:
648
649
650 arg0 := call.Args[0]
651 selx, _ := unparen(arg0).(*ast.SelectorExpr)
652 if selx == nil {
653 check.invalidArg(arg0, _BadOffsetofSyntax, "%s is not a selector expression", arg0)
654 check.use(arg0)
655 return
656 }
657
658 check.expr(x, selx.X)
659 if x.mode == invalid {
660 return
661 }
662
663 base := derefStructPtr(x.typ)
664 sel := selx.Sel.Name
665 obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
666 switch obj.(type) {
667 case nil:
668 check.invalidArg(x, _MissingFieldOrMethod, "%s has no single field %s", base, sel)
669 return
670 case *Func:
671
672
673
674
675 check.invalidArg(arg0, _InvalidOffsetof, "%s is a method value", arg0)
676 return
677 }
678 if indirect {
679 check.invalidArg(x, _InvalidOffsetof, "field %s is embedded via a pointer in %s", sel, base)
680 return
681 }
682
683
684 check.recordSelection(selx, FieldVal, base, obj, index, false)
685
686
687 {
688 mode := value
689 if x.mode == variable || indirect {
690 mode = variable
691 }
692 check.record(&operand{mode, selx, obj.Type(), nil, 0})
693 }
694
695
696
697
698
699 if hasVarSize(base, nil) {
700 x.mode = value
701 if check.Types != nil {
702 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
703 }
704 } else {
705 x.mode = constant_
706 x.val = constant.MakeInt64(check.conf.offsetof(base, index))
707
708 }
709 x.typ = Typ[Uintptr]
710
711 case _Sizeof:
712
713 check.assignment(x, nil, "argument to unsafe.Sizeof")
714 if x.mode == invalid {
715 return
716 }
717
718 if hasVarSize(x.typ, nil) {
719 x.mode = value
720 if check.Types != nil {
721 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
722 }
723 } else {
724 x.mode = constant_
725 x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
726
727 }
728 x.typ = Typ[Uintptr]
729
730 case _Slice:
731
732 if !check.allowVersion(check.pkg, 1, 17) {
733 check.errorf(call.Fun, _InvalidUnsafeSlice, "unsafe.Slice requires go1.17 or later")
734 return
735 }
736
737 typ, _ := under(x.typ).(*Pointer)
738 if typ == nil {
739 check.invalidArg(x, _InvalidUnsafeSlice, "%s is not a pointer", x)
740 return
741 }
742
743 var y operand
744 arg(&y, 1)
745 if !check.isValidIndex(&y, _InvalidUnsafeSlice, "length", false) {
746 return
747 }
748
749 x.mode = value
750 x.typ = NewSlice(typ.base)
751 if check.Types != nil {
752 check.recordBuiltinType(call.Fun, makeSig(x.typ, typ, y.typ))
753 }
754
755 case _Assert:
756
757
758
759 if x.mode != constant_ || !isBoolean(x.typ) {
760 check.invalidArg(x, _Test, "%s is not a boolean constant", x)
761 return
762 }
763 if x.val.Kind() != constant.Bool {
764 check.errorf(x, _Test, "internal error: value of %s should be a boolean constant", x)
765 return
766 }
767 if !constant.BoolVal(x.val) {
768 check.errorf(call, _Test, "%v failed", call)
769
770 }
771
772
773 case _Trace:
774
775
776
777
778
779 if nargs == 0 {
780 check.dump("%v: trace() without arguments", call.Pos())
781 x.mode = novalue
782 break
783 }
784 var t operand
785 x1 := x
786 for _, arg := range call.Args {
787 check.rawExpr(x1, arg, nil, false)
788 check.dump("%v: %s", x1.Pos(), x1)
789 x1 = &t
790 }
791
792
793 default:
794 unreachable()
795 }
796
797 return true
798 }
799
800
801
802
803 func hasVarSize(t Type, seen map[*Named]bool) (varSized bool) {
804
805
806
807 if named, _ := t.(*Named); named != nil {
808 if v, ok := seen[named]; ok {
809 return v
810 }
811 if seen == nil {
812 seen = make(map[*Named]bool)
813 }
814 seen[named] = true
815 defer func() {
816 seen[named] = varSized
817 }()
818 }
819
820 switch u := under(t).(type) {
821 case *Array:
822 return hasVarSize(u.elem, seen)
823 case *Struct:
824 for _, f := range u.fields {
825 if hasVarSize(f.typ, seen) {
826 return true
827 }
828 }
829 case *Interface:
830 return isTypeParam(t)
831 case *Named, *Union:
832 unreachable()
833 }
834 return false
835 }
836
837
838
839
840
841
842
843
844 func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
845 if tp, _ := x.typ.(*TypeParam); tp != nil {
846
847
848 var terms []*Term
849 if !tp.is(func(t *term) bool {
850 if t == nil {
851 return false
852 }
853 if r := f(t.typ); r != nil {
854 terms = append(terms, NewTerm(t.tilde, r))
855 return true
856 }
857 return false
858 }) {
859 return nil
860 }
861
862
863
864
865
866 var code errorCode
867 switch id {
868 case _Real:
869 code = _InvalidReal
870 case _Imag:
871 code = _InvalidImag
872 case _Complex:
873 code = _InvalidComplex
874 default:
875 unreachable()
876 }
877 check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see issue #50937)", x, predeclaredFuncs[id].name)
878
879
880
881
882 tpar := NewTypeName(token.NoPos, check.pkg, tp.obj.name, nil)
883 ptyp := check.newTypeParam(tpar, NewInterfaceType(nil, []Type{NewUnion(terms)}))
884 ptyp.index = tp.index
885
886 return ptyp
887 }
888
889 return f(x.typ)
890 }
891
892
893
894 func makeSig(res Type, args ...Type) *Signature {
895 list := make([]*Var, len(args))
896 for i, param := range args {
897 list[i] = NewVar(token.NoPos, nil, "", Default(param))
898 }
899 params := NewTuple(list...)
900 var result *Tuple
901 if res != nil {
902 assert(!isUntyped(res))
903 result = NewTuple(NewVar(token.NoPos, nil, "", res))
904 }
905 return &Signature{params: params, results: result}
906 }
907
908
909
910 func arrayPtrDeref(typ Type) Type {
911 if p, ok := typ.(*Pointer); ok {
912 if a, _ := under(p.base).(*Array); a != nil {
913 return a
914 }
915 }
916 return typ
917 }
918
919
920 func unparen(e ast.Expr) ast.Expr {
921 for {
922 p, ok := e.(*ast.ParenExpr)
923 if !ok {
924 return e
925 }
926 e = p.X
927 }
928 }
929
View as plain text