Daily bump.
[official-gcc.git] / libgo / go / go / types / builtins.go
blobc81e73c828840f76d97062330176497af9d1ec47
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // This file implements typechecking of builtin function calls.
7 package types
9 import (
10 "go/ast"
11 "go/constant"
12 "go/token"
15 // builtin type-checks a call to the built-in specified by id and
16 // reports whether the call is valid, with *x holding the result;
17 // but x.expr is not set. If the call is invalid, the result is
18 // false, and *x is undefined.
20 func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
21 // append is the only built-in that permits the use of ... for the last argument
22 bin := predeclaredFuncs[id]
23 if call.Ellipsis.IsValid() && id != _Append {
24 check.invalidOp(atPos(call.Ellipsis),
25 _InvalidDotDotDot,
26 "invalid use of ... with built-in %s", bin.name)
27 check.use(call.Args...)
28 return
31 // For len(x) and cap(x) we need to know if x contains any function calls or
32 // receive operations. Save/restore current setting and set hasCallOrRecv to
33 // false for the evaluation of x so that we can check it afterwards.
34 // Note: We must do this _before_ calling exprList because exprList evaluates
35 // all arguments.
36 if id == _Len || id == _Cap {
37 defer func(b bool) {
38 check.hasCallOrRecv = b
39 }(check.hasCallOrRecv)
40 check.hasCallOrRecv = false
43 // determine actual arguments
44 var arg func(*operand, int) // TODO(gri) remove use of arg getter in favor of using xlist directly
45 nargs := len(call.Args)
46 switch id {
47 default:
48 // make argument getter
49 xlist, _ := check.exprList(call.Args, false)
50 arg = func(x *operand, i int) { *x = *xlist[i] }
51 nargs = len(xlist)
52 // evaluate first argument, if present
53 if nargs > 0 {
54 arg(x, 0)
55 if x.mode == invalid {
56 return
59 case _Make, _New, _Offsetof, _Trace:
60 // arguments require special handling
63 // check argument count
65 msg := ""
66 if nargs < bin.nargs {
67 msg = "not enough"
68 } else if !bin.variadic && nargs > bin.nargs {
69 msg = "too many"
71 if msg != "" {
72 check.invalidOp(inNode(call, call.Rparen), _WrongArgCount, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
73 return
77 switch id {
78 case _Append:
79 // append(s S, x ...T) S, where T is the element type of S
80 // spec: "The variadic function append appends zero or more values x to s of type
81 // S, which must be a slice type, and returns the resulting slice, also of type S.
82 // The values x are passed to a parameter of type ...T where T is the element type
83 // of S and the respective parameter passing rules apply."
84 S := x.typ
85 var T Type
86 if s, _ := coreType(S).(*Slice); s != nil {
87 T = s.elem
88 } else {
89 var cause string
90 switch {
91 case x.isNil():
92 cause = "have untyped nil"
93 case isTypeParam(S):
94 if u := coreType(S); u != nil {
95 cause = check.sprintf("%s has core type %s", x, u)
96 } else {
97 cause = check.sprintf("%s has no core type", x)
99 default:
100 cause = check.sprintf("have %s", x)
102 // don't use Checker.invalidArg here as it would repeat "argument" in the error message
103 check.errorf(x, _InvalidAppend, "first argument to append must be a slice; %s", cause)
104 return
107 // remember arguments that have been evaluated already
108 alist := []operand{*x}
110 // spec: "As a special case, append also accepts a first argument assignable
111 // to type []byte with a second argument of string type followed by ... .
112 // This form appends the bytes of the string.
113 if nargs == 2 && call.Ellipsis.IsValid() {
114 if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
115 arg(x, 1)
116 if x.mode == invalid {
117 return
119 if t := coreString(x.typ); t != nil && isString(t) {
120 if check.Types != nil {
121 sig := makeSig(S, S, x.typ)
122 sig.variadic = true
123 check.recordBuiltinType(call.Fun, sig)
125 x.mode = value
126 x.typ = S
127 break
129 alist = append(alist, *x)
130 // fallthrough
134 // check general case by creating custom signature
135 sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
136 sig.variadic = true
137 var xlist []*operand
138 // convert []operand to []*operand
139 for i := range alist {
140 xlist = append(xlist, &alist[i])
142 for i := len(alist); i < nargs; i++ {
143 var x operand
144 arg(&x, i)
145 xlist = append(xlist, &x)
147 check.arguments(call, sig, nil, xlist, nil) // discard result (we know the result type)
148 // ok to continue even if check.arguments reported errors
150 x.mode = value
151 x.typ = S
152 if check.Types != nil {
153 check.recordBuiltinType(call.Fun, sig)
156 case _Cap, _Len:
157 // cap(x)
158 // len(x)
159 mode := invalid
160 var val constant.Value
161 switch t := arrayPtrDeref(under(x.typ)).(type) {
162 case *Basic:
163 if isString(t) && id == _Len {
164 if x.mode == constant_ {
165 mode = constant_
166 val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
167 } else {
168 mode = value
172 case *Array:
173 mode = value
174 // spec: "The expressions len(s) and cap(s) are constants
175 // if the type of s is an array or pointer to an array and
176 // the expression s does not contain channel receives or
177 // function calls; in this case s is not evaluated."
178 if !check.hasCallOrRecv {
179 mode = constant_
180 if t.len >= 0 {
181 val = constant.MakeInt64(t.len)
182 } else {
183 val = constant.MakeUnknown()
187 case *Slice, *Chan:
188 mode = value
190 case *Map:
191 if id == _Len {
192 mode = value
195 case *Interface:
196 if !isTypeParam(x.typ) {
197 break
199 if t.typeSet().underIs(func(t Type) bool {
200 switch t := arrayPtrDeref(t).(type) {
201 case *Basic:
202 if isString(t) && id == _Len {
203 return true
205 case *Array, *Slice, *Chan:
206 return true
207 case *Map:
208 if id == _Len {
209 return true
212 return false
213 }) {
214 mode = value
218 if mode == invalid && under(x.typ) != Typ[Invalid] {
219 code := _InvalidCap
220 if id == _Len {
221 code = _InvalidLen
223 check.invalidArg(x, code, "%s for %s", x, bin.name)
224 return
227 // record the signature before changing x.typ
228 if check.Types != nil && mode != constant_ {
229 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ))
232 x.mode = mode
233 x.typ = Typ[Int]
234 x.val = val
236 case _Close:
237 // close(c)
238 if !underIs(x.typ, func(u Type) bool {
239 uch, _ := u.(*Chan)
240 if uch == nil {
241 check.invalidOp(x, _InvalidClose, "cannot close non-channel %s", x)
242 return false
244 if uch.dir == RecvOnly {
245 check.invalidOp(x, _InvalidClose, "cannot close receive-only channel %s", x)
246 return false
248 return true
249 }) {
250 return
252 x.mode = novalue
253 if check.Types != nil {
254 check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
257 case _Complex:
258 // complex(x, y floatT) complexT
259 var y operand
260 arg(&y, 1)
261 if y.mode == invalid {
262 return
265 // convert or check untyped arguments
266 d := 0
267 if isUntyped(x.typ) {
268 d |= 1
270 if isUntyped(y.typ) {
271 d |= 2
273 switch d {
274 case 0:
275 // x and y are typed => nothing to do
276 case 1:
277 // only x is untyped => convert to type of y
278 check.convertUntyped(x, y.typ)
279 case 2:
280 // only y is untyped => convert to type of x
281 check.convertUntyped(&y, x.typ)
282 case 3:
283 // x and y are untyped =>
284 // 1) if both are constants, convert them to untyped
285 // floating-point numbers if possible,
286 // 2) if one of them is not constant (possible because
287 // it contains a shift that is yet untyped), convert
288 // both of them to float64 since they must have the
289 // same type to succeed (this will result in an error
290 // because shifts of floats are not permitted)
291 if x.mode == constant_ && y.mode == constant_ {
292 toFloat := func(x *operand) {
293 if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
294 x.typ = Typ[UntypedFloat]
297 toFloat(x)
298 toFloat(&y)
299 } else {
300 check.convertUntyped(x, Typ[Float64])
301 check.convertUntyped(&y, Typ[Float64])
302 // x and y should be invalid now, but be conservative
303 // and check below
306 if x.mode == invalid || y.mode == invalid {
307 return
310 // both argument types must be identical
311 if !Identical(x.typ, y.typ) {
312 check.invalidArg(x, _InvalidComplex, "mismatched types %s and %s", x.typ, y.typ)
313 return
316 // the argument types must be of floating-point type
317 // (applyTypeFunc never calls f with a type parameter)
318 f := func(typ Type) Type {
319 assert(!isTypeParam(typ))
320 if t, _ := under(typ).(*Basic); t != nil {
321 switch t.kind {
322 case Float32:
323 return Typ[Complex64]
324 case Float64:
325 return Typ[Complex128]
326 case UntypedFloat:
327 return Typ[UntypedComplex]
330 return nil
332 resTyp := check.applyTypeFunc(f, x, id)
333 if resTyp == nil {
334 check.invalidArg(x, _InvalidComplex, "arguments have type %s, expected floating-point", x.typ)
335 return
338 // if both arguments are constants, the result is a constant
339 if x.mode == constant_ && y.mode == constant_ {
340 x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
341 } else {
342 x.mode = value
345 if check.Types != nil && x.mode != constant_ {
346 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
349 x.typ = resTyp
351 case _Copy:
352 // copy(x, y []T) int
353 dst, _ := coreType(x.typ).(*Slice)
355 var y operand
356 arg(&y, 1)
357 if y.mode == invalid {
358 return
360 src0 := coreString(y.typ)
361 if src0 != nil && isString(src0) {
362 src0 = NewSlice(universeByte)
364 src, _ := src0.(*Slice)
366 if dst == nil || src == nil {
367 check.invalidArg(x, _InvalidCopy, "copy expects slice arguments; found %s and %s", x, &y)
368 return
371 if !Identical(dst.elem, src.elem) {
372 check.errorf(x, _InvalidCopy, "arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
373 return
376 if check.Types != nil {
377 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
379 x.mode = value
380 x.typ = Typ[Int]
382 case _Delete:
383 // delete(map_, key)
384 // map_ must be a map type or a type parameter describing map types.
385 // The key cannot be a type parameter for now.
386 map_ := x.typ
387 var key Type
388 if !underIs(map_, func(u Type) bool {
389 map_, _ := u.(*Map)
390 if map_ == nil {
391 check.invalidArg(x, _InvalidDelete, "%s is not a map", x)
392 return false
394 if key != nil && !Identical(map_.key, key) {
395 check.invalidArg(x, _InvalidDelete, "maps of %s must have identical key types", x)
396 return false
398 key = map_.key
399 return true
400 }) {
401 return
404 arg(x, 1) // k
405 if x.mode == invalid {
406 return
409 check.assignment(x, key, "argument to delete")
410 if x.mode == invalid {
411 return
414 x.mode = novalue
415 if check.Types != nil {
416 check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
419 case _Imag, _Real:
420 // imag(complexT) floatT
421 // real(complexT) floatT
423 // convert or check untyped argument
424 if isUntyped(x.typ) {
425 if x.mode == constant_ {
426 // an untyped constant number can always be considered
427 // as a complex constant
428 if isNumeric(x.typ) {
429 x.typ = Typ[UntypedComplex]
431 } else {
432 // an untyped non-constant argument may appear if
433 // it contains a (yet untyped non-constant) shift
434 // expression: convert it to complex128 which will
435 // result in an error (shift of complex value)
436 check.convertUntyped(x, Typ[Complex128])
437 // x should be invalid now, but be conservative and check
438 if x.mode == invalid {
439 return
444 // the argument must be of complex type
445 // (applyTypeFunc never calls f with a type parameter)
446 f := func(typ Type) Type {
447 assert(!isTypeParam(typ))
448 if t, _ := under(typ).(*Basic); t != nil {
449 switch t.kind {
450 case Complex64:
451 return Typ[Float32]
452 case Complex128:
453 return Typ[Float64]
454 case UntypedComplex:
455 return Typ[UntypedFloat]
458 return nil
460 resTyp := check.applyTypeFunc(f, x, id)
461 if resTyp == nil {
462 code := _InvalidImag
463 if id == _Real {
464 code = _InvalidReal
466 check.invalidArg(x, code, "argument has type %s, expected complex type", x.typ)
467 return
470 // if the argument is a constant, the result is a constant
471 if x.mode == constant_ {
472 if id == _Real {
473 x.val = constant.Real(x.val)
474 } else {
475 x.val = constant.Imag(x.val)
477 } else {
478 x.mode = value
481 if check.Types != nil && x.mode != constant_ {
482 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
485 x.typ = resTyp
487 case _Make:
488 // make(T, n)
489 // make(T, n, m)
490 // (no argument evaluated yet)
491 arg0 := call.Args[0]
492 T := check.varType(arg0)
493 if T == Typ[Invalid] {
494 return
497 var min int // minimum number of arguments
498 switch coreType(T).(type) {
499 case *Slice:
500 min = 2
501 case *Map, *Chan:
502 min = 1
503 case nil:
504 check.errorf(arg0, _InvalidMake, "cannot make %s: no core type", arg0)
505 return
506 default:
507 check.invalidArg(arg0, _InvalidMake, "cannot make %s; type must be slice, map, or channel", arg0)
508 return
510 if nargs < min || min+1 < nargs {
511 check.invalidOp(call, _WrongArgCount, "%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
512 return
515 types := []Type{T}
516 var sizes []int64 // constant integer arguments, if any
517 for _, arg := range call.Args[1:] {
518 typ, size := check.index(arg, -1) // ok to continue with typ == Typ[Invalid]
519 types = append(types, typ)
520 if size >= 0 {
521 sizes = append(sizes, size)
524 if len(sizes) == 2 && sizes[0] > sizes[1] {
525 check.invalidArg(call.Args[1], _SwappedMakeArgs, "length and capacity swapped")
526 // safe to continue
528 x.mode = value
529 x.typ = T
530 if check.Types != nil {
531 check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
534 case _New:
535 // new(T)
536 // (no argument evaluated yet)
537 T := check.varType(call.Args[0])
538 if T == Typ[Invalid] {
539 return
542 x.mode = value
543 x.typ = &Pointer{base: T}
544 if check.Types != nil {
545 check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
548 case _Panic:
549 // panic(x)
550 // record panic call if inside a function with result parameters
551 // (for use in Checker.isTerminating)
552 if check.sig != nil && check.sig.results.Len() > 0 {
553 // function has result parameters
554 p := check.isPanic
555 if p == nil {
556 // allocate lazily
557 p = make(map[*ast.CallExpr]bool)
558 check.isPanic = p
560 p[call] = true
563 check.assignment(x, &emptyInterface, "argument to panic")
564 if x.mode == invalid {
565 return
568 x.mode = novalue
569 if check.Types != nil {
570 check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
573 case _Print, _Println:
574 // print(x, y, ...)
575 // println(x, y, ...)
576 var params []Type
577 if nargs > 0 {
578 params = make([]Type, nargs)
579 for i := 0; i < nargs; i++ {
580 if i > 0 {
581 arg(x, i) // first argument already evaluated
583 check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
584 if x.mode == invalid {
585 // TODO(gri) "use" all arguments?
586 return
588 params[i] = x.typ
592 x.mode = novalue
593 if check.Types != nil {
594 check.recordBuiltinType(call.Fun, makeSig(nil, params...))
597 case _Recover:
598 // recover() interface{}
599 x.mode = value
600 x.typ = &emptyInterface
601 if check.Types != nil {
602 check.recordBuiltinType(call.Fun, makeSig(x.typ))
605 case _Add:
606 // unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
607 if !check.allowVersion(check.pkg, 1, 17) {
608 check.errorf(call.Fun, _InvalidUnsafeAdd, "unsafe.Add requires go1.17 or later")
609 return
612 check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
613 if x.mode == invalid {
614 return
617 var y operand
618 arg(&y, 1)
619 if !check.isValidIndex(&y, _InvalidUnsafeAdd, "length", true) {
620 return
623 x.mode = value
624 x.typ = Typ[UnsafePointer]
625 if check.Types != nil {
626 check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
629 case _Alignof:
630 // unsafe.Alignof(x T) uintptr
631 check.assignment(x, nil, "argument to unsafe.Alignof")
632 if x.mode == invalid {
633 return
636 if hasVarSize(x.typ) {
637 x.mode = value
638 if check.Types != nil {
639 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
641 } else {
642 x.mode = constant_
643 x.val = constant.MakeInt64(check.conf.alignof(x.typ))
644 // result is constant - no need to record signature
646 x.typ = Typ[Uintptr]
648 case _Offsetof:
649 // unsafe.Offsetof(x T) uintptr, where x must be a selector
650 // (no argument evaluated yet)
651 arg0 := call.Args[0]
652 selx, _ := unparen(arg0).(*ast.SelectorExpr)
653 if selx == nil {
654 check.invalidArg(arg0, _BadOffsetofSyntax, "%s is not a selector expression", arg0)
655 check.use(arg0)
656 return
659 check.expr(x, selx.X)
660 if x.mode == invalid {
661 return
664 base := derefStructPtr(x.typ)
665 sel := selx.Sel.Name
666 obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
667 switch obj.(type) {
668 case nil:
669 check.invalidArg(x, _MissingFieldOrMethod, "%s has no single field %s", base, sel)
670 return
671 case *Func:
672 // TODO(gri) Using derefStructPtr may result in methods being found
673 // that don't actually exist. An error either way, but the error
674 // message is confusing. See: https://play.golang.org/p/al75v23kUy ,
675 // but go/types reports: "invalid argument: x.m is a method value".
676 check.invalidArg(arg0, _InvalidOffsetof, "%s is a method value", arg0)
677 return
679 if indirect {
680 check.invalidArg(x, _InvalidOffsetof, "field %s is embedded via a pointer in %s", sel, base)
681 return
684 // TODO(gri) Should we pass x.typ instead of base (and have indirect report if derefStructPtr indirected)?
685 check.recordSelection(selx, FieldVal, base, obj, index, false)
687 // record the selector expression (was bug - issue #47895)
689 mode := value
690 if x.mode == variable || indirect {
691 mode = variable
693 check.record(&operand{mode, selx, obj.Type(), nil, 0})
696 // The field offset is considered a variable even if the field is declared before
697 // the part of the struct which is variable-sized. This makes both the rules
698 // simpler and also permits (or at least doesn't prevent) a compiler from re-
699 // arranging struct fields if it wanted to.
700 if hasVarSize(base) {
701 x.mode = value
702 if check.Types != nil {
703 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
705 } else {
706 x.mode = constant_
707 x.val = constant.MakeInt64(check.conf.offsetof(base, index))
708 // result is constant - no need to record signature
710 x.typ = Typ[Uintptr]
712 case _Sizeof:
713 // unsafe.Sizeof(x T) uintptr
714 check.assignment(x, nil, "argument to unsafe.Sizeof")
715 if x.mode == invalid {
716 return
719 if hasVarSize(x.typ) {
720 x.mode = value
721 if check.Types != nil {
722 check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
724 } else {
725 x.mode = constant_
726 x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
727 // result is constant - no need to record signature
729 x.typ = Typ[Uintptr]
731 case _Slice:
732 // unsafe.Slice(ptr *T, len IntegerType) []T
733 if !check.allowVersion(check.pkg, 1, 17) {
734 check.errorf(call.Fun, _InvalidUnsafeSlice, "unsafe.Slice requires go1.17 or later")
735 return
738 typ, _ := under(x.typ).(*Pointer)
739 if typ == nil {
740 check.invalidArg(x, _InvalidUnsafeSlice, "%s is not a pointer", x)
741 return
744 var y operand
745 arg(&y, 1)
746 if !check.isValidIndex(&y, _InvalidUnsafeSlice, "length", false) {
747 return
750 x.mode = value
751 x.typ = NewSlice(typ.base)
752 if check.Types != nil {
753 check.recordBuiltinType(call.Fun, makeSig(x.typ, typ, y.typ))
756 case _Assert:
757 // assert(pred) causes a typechecker error if pred is false.
758 // The result of assert is the value of pred if there is no error.
759 // Note: assert is only available in self-test mode.
760 if x.mode != constant_ || !isBoolean(x.typ) {
761 check.invalidArg(x, _Test, "%s is not a boolean constant", x)
762 return
764 if x.val.Kind() != constant.Bool {
765 check.errorf(x, _Test, "internal error: value of %s should be a boolean constant", x)
766 return
768 if !constant.BoolVal(x.val) {
769 check.errorf(call, _Test, "%v failed", call)
770 // compile-time assertion failure - safe to continue
772 // result is constant - no need to record signature
774 case _Trace:
775 // trace(x, y, z, ...) dumps the positions, expressions, and
776 // values of its arguments. The result of trace is the value
777 // of the first argument.
778 // Note: trace is only available in self-test mode.
779 // (no argument evaluated yet)
780 if nargs == 0 {
781 check.dump("%v: trace() without arguments", call.Pos())
782 x.mode = novalue
783 break
785 var t operand
786 x1 := x
787 for _, arg := range call.Args {
788 check.rawExpr(x1, arg, nil, false) // permit trace for types, e.g.: new(trace(T))
789 check.dump("%v: %s", x1.Pos(), x1)
790 x1 = &t // use incoming x only for first argument
792 // trace is only available in test mode - no need to record signature
794 default:
795 unreachable()
798 return true
801 // hasVarSize reports if the size of type t is variable due to type parameters.
802 func hasVarSize(t Type) bool {
803 switch u := under(t).(type) {
804 case *Array:
805 return hasVarSize(u.elem)
806 case *Struct:
807 for _, f := range u.fields {
808 if hasVarSize(f.typ) {
809 return true
812 case *Interface:
813 return isTypeParam(t)
814 case *Named, *Union:
815 unreachable()
817 return false
820 // applyTypeFunc applies f to x. If x is a type parameter,
821 // the result is a type parameter constrained by an new
822 // interface bound. The type bounds for that interface
823 // are computed by applying f to each of the type bounds
824 // of x. If any of these applications of f return nil,
825 // applyTypeFunc returns nil.
826 // If x is not a type parameter, the result is f(x).
827 func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
828 if tp, _ := x.typ.(*TypeParam); tp != nil {
829 // Test if t satisfies the requirements for the argument
830 // type and collect possible result types at the same time.
831 var terms []*Term
832 if !tp.is(func(t *term) bool {
833 if t == nil {
834 return false
836 if r := f(t.typ); r != nil {
837 terms = append(terms, NewTerm(t.tilde, r))
838 return true
840 return false
841 }) {
842 return nil
845 // We can type-check this fine but we're introducing a synthetic
846 // type parameter for the result. It's not clear what the API
847 // implications are here. Report an error for 1.18 (see #50912),
848 // but continue type-checking.
849 var code errorCode
850 switch id {
851 case _Real:
852 code = _InvalidReal
853 case _Imag:
854 code = _InvalidImag
855 case _Complex:
856 code = _InvalidComplex
857 default:
858 unreachable()
860 check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see issue #50937)", x, predeclaredFuncs[id].name)
862 // Construct a suitable new type parameter for the result type.
863 // The type parameter is placed in the current package so export/import
864 // works as expected.
865 tpar := NewTypeName(token.NoPos, check.pkg, tp.obj.name, nil)
866 ptyp := check.newTypeParam(tpar, NewInterfaceType(nil, []Type{NewUnion(terms)})) // assigns type to tpar as a side-effect
867 ptyp.index = tp.index
869 return ptyp
872 return f(x.typ)
875 // makeSig makes a signature for the given argument and result types.
876 // Default types are used for untyped arguments, and res may be nil.
877 func makeSig(res Type, args ...Type) *Signature {
878 list := make([]*Var, len(args))
879 for i, param := range args {
880 list[i] = NewVar(token.NoPos, nil, "", Default(param))
882 params := NewTuple(list...)
883 var result *Tuple
884 if res != nil {
885 assert(!isUntyped(res))
886 result = NewTuple(NewVar(token.NoPos, nil, "", res))
888 return &Signature{params: params, results: result}
891 // arrayPtrDeref returns A if typ is of the form *A and A is an array;
892 // otherwise it returns typ.
893 func arrayPtrDeref(typ Type) Type {
894 if p, ok := typ.(*Pointer); ok {
895 if a, _ := under(p.base).(*Array); a != nil {
896 return a
899 return typ
902 // unparen returns e with any enclosing parentheses stripped.
903 func unparen(e ast.Expr) ast.Expr {
904 for {
905 p, ok := e.(*ast.ParenExpr)
906 if !ok {
907 return e
909 e = p.X