Source file src/go/types/builtins.go

     1  // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
     2  // Source: ../../cmd/compile/internal/types2/builtins.go
     3  
     4  // Copyright 2012 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  // This file implements typechecking of builtin function calls.
     9  
    10  package types
    11  
    12  import (
    13  	"go/ast"
    14  	"go/constant"
    15  	"go/token"
    16  	. "internal/types/errors"
    17  )
    18  
    19  // builtin type-checks a call to the built-in specified by id and
    20  // reports whether the call is valid, with *x holding the result;
    21  // but x.expr is not set. If the call is invalid, the result is
    22  // false, and *x is undefined.
    23  func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
    24  	argList := call.Args
    25  
    26  	// append is the only built-in that permits the use of ... for the last argument
    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  	// For len(x) and cap(x) we need to know if x contains any function calls or
    37  	// receive operations. Save/restore current setting and set hasCallOrRecv to
    38  	// false for the evaluation of x so that we can check it afterwards.
    39  	// Note: We must do this _before_ calling exprList because exprList evaluates
    40  	//       all arguments.
    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  	// Evaluate arguments for built-ins that use ordinary (value) arguments.
    49  	// For built-ins with special argument handling (make, new, etc.),
    50  	// evaluation is done by the respective built-in code.
    51  	var args []*operand // not valid for _Make, _New, _Offsetof, _Trace
    52  	var nargs int
    53  	switch id {
    54  	default:
    55  		// check all arguments
    56  		args = check.exprList(argList)
    57  		nargs = len(args)
    58  		for _, a := range args {
    59  			if a.mode == invalid {
    60  				return
    61  			}
    62  		}
    63  		// first argument is always in x
    64  		if nargs > 0 {
    65  			*x = *args[0]
    66  		}
    67  	case _Make, _New, _Offsetof, _Trace:
    68  		// arguments require special handling
    69  		nargs = len(argList)
    70  	}
    71  
    72  	// check argument count
    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  		// append(s S, x ...E) S, where E is the element type of S
    89  		// spec: "The variadic function append appends zero or more values x to
    90  		// a slice s of type S and returns the resulting slice, also of type S.
    91  		// The values x are passed to a parameter of type ...E where E is the
    92  		// element type of S and the respective parameter passing rules apply.
    93  		// As a special case, append also accepts a first argument assignable
    94  		// to type []byte with a second argument of string type followed by ... .
    95  		// This form appends the bytes of the string."
    96  
    97  		// In either case, the first argument must be a slice; in particular it
    98  		// cannot be the predeclared nil value. Note that nil is not excluded by
    99  		// the assignability requirement alone for the special case (go.dev/issue/76220).
   100  		// spec: "If S is a type parameter, all types in its type set
   101  		// must have the same underlying slice type []E."
   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  		// Handle append(bytes, y...) special case, where
   109  		// the type set of y is {string} or {string, []byte}.
   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  						// typeset ⊇ {[]byte}
   118  					} else if isString(u) {
   119  						// typeset ⊇ {string}
   120  						hasString = true
   121  					} else {
   122  						y = nil
   123  						break
   124  					}
   125  				}
   126  				if y != nil && hasString {
   127  					// setting the signature also signals that we're done
   128  					sig = makeSig(x.typ, x.typ, y.typ)
   129  					sig.variadic = true
   130  				}
   131  			}
   132  		}
   133  
   134  		// general case
   135  		if sig == nil {
   136  			// check arguments by creating custom signature
   137  			sig = makeSig(x.typ, x.typ, NewSlice(E)) // []E required for variadic signature
   138  			sig.variadic = true
   139  			check.arguments(call, sig, nil, nil, args, nil) // discard result (we know the result type)
   140  			// ok to continue even if check.arguments reported errors
   141  		}
   142  
   143  		if check.recordTypes() {
   144  			check.recordBuiltinType(call.Fun, sig)
   145  		}
   146  		x.mode = value
   147  		// x.typ is unchanged
   148  
   149  	case _Cap, _Len:
   150  		// cap(x)
   151  		// len(x)
   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(int64(len(constant.StringVal(x.val))))
   160  				} else {
   161  					mode = value
   162  				}
   163  			}
   164  
   165  		case *Array:
   166  			mode = value
   167  			// spec: "The expressions len(s) and cap(s) are constants
   168  			// if the type of s is an array or pointer to an array and
   169  			// the expression s does not contain channel receives or
   170  			// function calls; in this case s is not evaluated."
   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  			// avoid error if underlying type is invalid
   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  		// record the signature before changing x.typ
   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  		// clear(m)
   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  		// close(c)
   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  		// complex(x, y floatT) complexT
   275  		y := args[1]
   276  
   277  		// convert or check untyped arguments
   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  			// x and y are typed => nothing to do
   288  		case 1:
   289  			// only x is untyped => convert to type of y
   290  			check.convertUntyped(x, y.typ)
   291  		case 2:
   292  			// only y is untyped => convert to type of x
   293  			check.convertUntyped(y, x.typ)
   294  		case 3:
   295  			// x and y are untyped =>
   296  			// 1) if both are constants, convert them to untyped
   297  			//    floating-point numbers if possible,
   298  			// 2) if one of them is not constant (possible because
   299  			//    it contains a shift that is yet untyped), convert
   300  			//    both of them to float64 since they must have the
   301  			//    same type to succeed (this will result in an error
   302  			//    because shifts of floats are not permitted)
   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  				// x and y should be invalid now, but be conservative
   315  				// and check below
   316  			}
   317  		}
   318  		if x.mode == invalid || y.mode == invalid {
   319  			return
   320  		}
   321  
   322  		// both argument types must be identical
   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  		// the argument types must be of floating-point type
   329  		// (applyTypeFunc never calls f with a type parameter)
   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  		// if both arguments are constants, the result is a constant
   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  		// copy(x, y []E) int
   365  		// spec: "The function copy copies slice elements from a source src to a destination
   366  		// dst and returns the number of elements copied. Both arguments must have identical
   367  		// element type E and must be assignable to a slice of type []E.
   368  		// The number of elements copied is the minimum of len(src) and len(dst).
   369  		// As a special case, copy also accepts a destination argument assignable to type
   370  		// []byte with a source argument of a string type.
   371  		// This form copies the bytes from the string into the byte slice."
   372  
   373  		// get special case out of the way
   374  		y := args[1]
   375  		var special bool
   376  		if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
   377  			special = true
   378  			for _, u := range typeset(y.typ) {
   379  				if s, _ := u.(*Slice); s != nil && Identical(s.elem, universeByte) {
   380  					// typeset ⊇ {[]byte}
   381  				} else if isString(u) {
   382  					// typeset ⊇ {string}
   383  				} else {
   384  					special = false
   385  					break
   386  				}
   387  			}
   388  		}
   389  
   390  		// general case
   391  		if !special {
   392  			// spec: "If the type of one or both arguments is a type parameter, all types
   393  			// in their respective type sets must have the same underlying slice type []E."
   394  			dstE, err := sliceElem(x)
   395  			if err != nil {
   396  				check.errorf(x, InvalidCopy, "invalid copy: %s", err.format(check))
   397  				return
   398  			}
   399  			srcE, err := sliceElem(y)
   400  			if err != nil {
   401  				// If we have a string, for a better error message proceed with byte element type.
   402  				if !allString(y.typ) {
   403  					check.errorf(y, InvalidCopy, "invalid copy: %s", err.format(check))
   404  					return
   405  				}
   406  				srcE = universeByte
   407  			}
   408  			if !Identical(dstE, srcE) {
   409  				check.errorf(x, InvalidCopy, "invalid copy: arguments %s and %s have different element types %s and %s", x, y, dstE, srcE)
   410  				return
   411  			}
   412  		}
   413  
   414  		if check.recordTypes() {
   415  			check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
   416  		}
   417  		x.mode = value
   418  		x.typ = Typ[Int]
   419  
   420  	case _Delete:
   421  		// delete(map_, key)
   422  		// map_ must be a map type or a type parameter describing map types.
   423  		// The key cannot be a type parameter for now.
   424  		map_ := x.typ
   425  		var key Type
   426  		if !underIs(map_, func(u Type) bool {
   427  			map_, _ := u.(*Map)
   428  			if map_ == nil {
   429  				check.errorf(x, InvalidDelete, invalidArg+"%s is not a map", x)
   430  				return false
   431  			}
   432  			if key != nil && !Identical(map_.key, key) {
   433  				check.errorf(x, InvalidDelete, invalidArg+"maps of %s must have identical key types", x)
   434  				return false
   435  			}
   436  			key = map_.key
   437  			return true
   438  		}) {
   439  			return
   440  		}
   441  
   442  		*x = *args[1] // key
   443  		check.assignment(x, key, "argument to delete")
   444  		if x.mode == invalid {
   445  			return
   446  		}
   447  
   448  		x.mode = novalue
   449  		if check.recordTypes() {
   450  			check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
   451  		}
   452  
   453  	case _Imag, _Real:
   454  		// imag(complexT) floatT
   455  		// real(complexT) floatT
   456  
   457  		// convert or check untyped argument
   458  		if isUntyped(x.typ) {
   459  			if x.mode == constant_ {
   460  				// an untyped constant number can always be considered
   461  				// as a complex constant
   462  				if isNumeric(x.typ) {
   463  					x.typ = Typ[UntypedComplex]
   464  				}
   465  			} else {
   466  				// an untyped non-constant argument may appear if
   467  				// it contains a (yet untyped non-constant) shift
   468  				// expression: convert it to complex128 which will
   469  				// result in an error (shift of complex value)
   470  				check.convertUntyped(x, Typ[Complex128])
   471  				// x should be invalid now, but be conservative and check
   472  				if x.mode == invalid {
   473  					return
   474  				}
   475  			}
   476  		}
   477  
   478  		// the argument must be of complex type
   479  		// (applyTypeFunc never calls f with a type parameter)
   480  		f := func(typ Type) Type {
   481  			assert(!isTypeParam(typ))
   482  			if t, _ := typ.Underlying().(*Basic); t != nil {
   483  				switch t.kind {
   484  				case Complex64:
   485  					return Typ[Float32]
   486  				case Complex128:
   487  					return Typ[Float64]
   488  				case UntypedComplex:
   489  					return Typ[UntypedFloat]
   490  				}
   491  			}
   492  			return nil
   493  		}
   494  		resTyp := check.applyTypeFunc(f, x, id)
   495  		if resTyp == nil {
   496  			code := InvalidImag
   497  			if id == _Real {
   498  				code = InvalidReal
   499  			}
   500  			check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ)
   501  			return
   502  		}
   503  
   504  		// if the argument is a constant, the result is a constant
   505  		if x.mode == constant_ {
   506  			if id == _Real {
   507  				x.val = constant.Real(x.val)
   508  			} else {
   509  				x.val = constant.Imag(x.val)
   510  			}
   511  		} else {
   512  			x.mode = value
   513  		}
   514  
   515  		if check.recordTypes() && x.mode != constant_ {
   516  			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
   517  		}
   518  
   519  		x.typ = resTyp
   520  
   521  	case _Make:
   522  		// make(T, n)
   523  		// make(T, n, m)
   524  		// (no argument evaluated yet)
   525  		arg0 := argList[0]
   526  		T := check.varType(arg0)
   527  		if !isValid(T) {
   528  			return
   529  		}
   530  
   531  		u, err := commonUnder(T, func(_, u Type) *typeError {
   532  			switch u.(type) {
   533  			case *Slice, *Map, *Chan:
   534  				return nil // ok
   535  			case nil:
   536  				return typeErrorf("no specific type")
   537  			default:
   538  				return typeErrorf("type must be slice, map, or channel")
   539  			}
   540  		})
   541  		if err != nil {
   542  			check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s: %s", arg0, err.format(check))
   543  			return
   544  		}
   545  
   546  		var min int // minimum number of arguments
   547  		switch u.(type) {
   548  		case *Slice:
   549  			min = 2
   550  		case *Map, *Chan:
   551  			min = 1
   552  		default:
   553  			// any other type was excluded above
   554  			panic("unreachable")
   555  		}
   556  		if nargs < min || min+1 < nargs {
   557  			check.errorf(call, WrongArgCount, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
   558  			return
   559  		}
   560  
   561  		types := []Type{T}
   562  		var sizes []int64 // constant integer arguments, if any
   563  		for _, arg := range argList[1:] {
   564  			typ, size := check.index(arg, -1) // ok to continue with typ == Typ[Invalid]
   565  			types = append(types, typ)
   566  			if size >= 0 {
   567  				sizes = append(sizes, size)
   568  			}
   569  		}
   570  		if len(sizes) == 2 && sizes[0] > sizes[1] {
   571  			check.error(argList[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
   572  			// safe to continue
   573  		}
   574  		x.mode = value
   575  		x.typ = T
   576  		if check.recordTypes() {
   577  			check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
   578  		}
   579  
   580  	case _Max, _Min:
   581  		// max(x, ...)
   582  		// min(x, ...)
   583  		check.verifyVersionf(call.Fun, go1_21, "built-in %s", bin.name)
   584  
   585  		op := token.LSS
   586  		if id == _Max {
   587  			op = token.GTR
   588  		}
   589  
   590  		for i, a := range args {
   591  			if a.mode == invalid {
   592  				return
   593  			}
   594  
   595  			if !allOrdered(a.typ) {
   596  				check.errorf(a, InvalidMinMaxOperand, invalidArg+"%s cannot be ordered", a)
   597  				return
   598  			}
   599  
   600  			// The first argument is already in x and there's nothing left to do.
   601  			if i > 0 {
   602  				check.matchTypes(x, a)
   603  				if x.mode == invalid {
   604  					return
   605  				}
   606  
   607  				if !Identical(x.typ, a.typ) {
   608  					check.errorf(a, MismatchedTypes, invalidArg+"mismatched types %s (previous argument) and %s (type of %s)", x.typ, a.typ, a.expr)
   609  					return
   610  				}
   611  
   612  				if x.mode == constant_ && a.mode == constant_ {
   613  					if constant.Compare(a.val, op, x.val) {
   614  						*x = *a
   615  					}
   616  				} else {
   617  					x.mode = value
   618  				}
   619  			}
   620  		}
   621  
   622  		// If nargs == 1, make sure x.mode is either a value or a constant.
   623  		if x.mode != constant_ {
   624  			x.mode = value
   625  			// A value must not be untyped.
   626  			check.assignment(x, &emptyInterface, "argument to built-in "+bin.name)
   627  			if x.mode == invalid {
   628  				return
   629  			}
   630  		}
   631  
   632  		// Use the final type computed above for all arguments.
   633  		for _, a := range args {
   634  			check.updateExprType(a.expr, x.typ, true)
   635  		}
   636  
   637  		if check.recordTypes() && x.mode != constant_ {
   638  			types := make([]Type, nargs)
   639  			for i := range types {
   640  				types[i] = x.typ
   641  			}
   642  			check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
   643  		}
   644  
   645  	case _New:
   646  		// new(T) or new(expr)
   647  		// (no argument evaluated yet)
   648  		arg := argList[0]
   649  		check.exprOrType(x, arg, false)
   650  		check.exclude(x, 1<<novalue|1<<builtin)
   651  		switch x.mode {
   652  		case invalid:
   653  			return
   654  		case typexpr:
   655  			// new(T)
   656  			check.validVarType(arg, x.typ)
   657  		default:
   658  			// new(expr)
   659  			if isUntyped(x.typ) {
   660  				// check for overflow and untyped nil
   661  				check.assignment(x, nil, "argument to new")
   662  				if x.mode == invalid {
   663  					return
   664  				}
   665  				assert(isTyped(x.typ))
   666  			}
   667  			// report version error only if there are no other errors
   668  			check.verifyVersionf(call.Fun, go1_26, "new(%s)", arg)
   669  		}
   670  
   671  		T := x.typ
   672  		x.mode = value
   673  		x.typ = NewPointer(T)
   674  		if check.recordTypes() {
   675  			check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
   676  		}
   677  
   678  	case _Panic:
   679  		// panic(x)
   680  		// record panic call if inside a function with result parameters
   681  		// (for use in Checker.isTerminating)
   682  		if check.sig != nil && check.sig.results.Len() > 0 {
   683  			// function has result parameters
   684  			p := check.isPanic
   685  			if p == nil {
   686  				// allocate lazily
   687  				p = make(map[*ast.CallExpr]bool)
   688  				check.isPanic = p
   689  			}
   690  			p[call] = true
   691  		}
   692  
   693  		check.assignment(x, &emptyInterface, "argument to panic")
   694  		if x.mode == invalid {
   695  			return
   696  		}
   697  
   698  		x.mode = novalue
   699  		if check.recordTypes() {
   700  			check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
   701  		}
   702  
   703  	case _Print, _Println:
   704  		// print(x, y, ...)
   705  		// println(x, y, ...)
   706  		var params []Type
   707  		if nargs > 0 {
   708  			params = make([]Type, nargs)
   709  			for i, a := range args {
   710  				check.assignment(a, nil, "argument to built-in "+predeclaredFuncs[id].name)
   711  				if a.mode == invalid {
   712  					return
   713  				}
   714  				params[i] = a.typ
   715  			}
   716  		}
   717  
   718  		x.mode = novalue
   719  		if check.recordTypes() {
   720  			check.recordBuiltinType(call.Fun, makeSig(nil, params...))
   721  		}
   722  
   723  	case _Recover:
   724  		// recover() interface{}
   725  		x.mode = value
   726  		x.typ = &emptyInterface
   727  		if check.recordTypes() {
   728  			check.recordBuiltinType(call.Fun, makeSig(x.typ))
   729  		}
   730  
   731  	case _Add:
   732  		// unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
   733  		check.verifyVersionf(call.Fun, go1_17, "unsafe.Add")
   734  
   735  		check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
   736  		if x.mode == invalid {
   737  			return
   738  		}
   739  
   740  		y := args[1]
   741  		if !check.isValidIndex(y, InvalidUnsafeAdd, "length", true) {
   742  			return
   743  		}
   744  
   745  		x.mode = value
   746  		x.typ = Typ[UnsafePointer]
   747  		if check.recordTypes() {
   748  			check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
   749  		}
   750  
   751  	case _Alignof:
   752  		// unsafe.Alignof(x T) uintptr
   753  		check.assignment(x, nil, "argument to unsafe.Alignof")
   754  		if x.mode == invalid {
   755  			return
   756  		}
   757  
   758  		if hasVarSize(x.typ, nil) {
   759  			x.mode = value
   760  			if check.recordTypes() {
   761  				check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
   762  			}
   763  		} else {
   764  			x.mode = constant_
   765  			x.val = constant.MakeInt64(check.conf.alignof(x.typ))
   766  			// result is constant - no need to record signature
   767  		}
   768  		x.typ = Typ[Uintptr]
   769  
   770  	case _Offsetof:
   771  		// unsafe.Offsetof(x T) uintptr, where x must be a selector
   772  		// (no argument evaluated yet)
   773  		arg0 := argList[0]
   774  		selx, _ := ast.Unparen(arg0).(*ast.SelectorExpr)
   775  		if selx == nil {
   776  			check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
   777  			check.use(arg0)
   778  			return
   779  		}
   780  
   781  		check.expr(nil, x, selx.X)
   782  		if x.mode == invalid {
   783  			return
   784  		}
   785  
   786  		base := derefStructPtr(x.typ)
   787  		sel := selx.Sel.Name
   788  		obj, index, indirect := lookupFieldOrMethod(base, false, check.pkg, sel, false)
   789  		switch obj.(type) {
   790  		case nil:
   791  			check.errorf(x, MissingFieldOrMethod, invalidArg+"%s has no single field %s", base, sel)
   792  			return
   793  		case *Func:
   794  			// TODO(gri) Using derefStructPtr may result in methods being found
   795  			// that don't actually exist. An error either way, but the error
   796  			// message is confusing. See: https://play.golang.org/p/al75v23kUy ,
   797  			// but go/types reports: "invalid argument: x.m is a method value".
   798  			check.errorf(arg0, InvalidOffsetof, invalidArg+"%s is a method value", arg0)
   799  			return
   800  		}
   801  		if indirect {
   802  			check.errorf(x, InvalidOffsetof, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
   803  			return
   804  		}
   805  
   806  		// TODO(gri) Should we pass x.typ instead of base (and have indirect report if derefStructPtr indirected)?
   807  		check.recordSelection(selx, FieldVal, base, obj, index, false)
   808  
   809  		// record the selector expression (was bug - go.dev/issue/47895)
   810  		{
   811  			mode := value
   812  			if x.mode == variable || indirect {
   813  				mode = variable
   814  			}
   815  			check.record(&operand{mode, selx, obj.Type(), nil, 0})
   816  		}
   817  
   818  		// The field offset is considered a variable even if the field is declared before
   819  		// the part of the struct which is variable-sized. This makes both the rules
   820  		// simpler and also permits (or at least doesn't prevent) a compiler from re-
   821  		// arranging struct fields if it wanted to.
   822  		if hasVarSize(base, nil) {
   823  			x.mode = value
   824  			if check.recordTypes() {
   825  				check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
   826  			}
   827  		} else {
   828  			offs := check.conf.offsetof(base, index)
   829  			if offs < 0 {
   830  				check.errorf(x, TypeTooLarge, "%s is too large", x)
   831  				return
   832  			}
   833  			x.mode = constant_
   834  			x.val = constant.MakeInt64(offs)
   835  			// result is constant - no need to record signature
   836  		}
   837  		x.typ = Typ[Uintptr]
   838  
   839  	case _Sizeof:
   840  		// unsafe.Sizeof(x T) uintptr
   841  		check.assignment(x, nil, "argument to unsafe.Sizeof")
   842  		if x.mode == invalid {
   843  			return
   844  		}
   845  
   846  		if hasVarSize(x.typ, nil) {
   847  			x.mode = value
   848  			if check.recordTypes() {
   849  				check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
   850  			}
   851  		} else {
   852  			size := check.conf.sizeof(x.typ)
   853  			if size < 0 {
   854  				check.errorf(x, TypeTooLarge, "%s is too large", x)
   855  				return
   856  			}
   857  			x.mode = constant_
   858  			x.val = constant.MakeInt64(size)
   859  			// result is constant - no need to record signature
   860  		}
   861  		x.typ = Typ[Uintptr]
   862  
   863  	case _Slice:
   864  		// unsafe.Slice(ptr *T, len IntegerType) []T
   865  		check.verifyVersionf(call.Fun, go1_17, "unsafe.Slice")
   866  
   867  		u, _ := commonUnder(x.typ, nil)
   868  		ptr, _ := u.(*Pointer)
   869  		if ptr == nil {
   870  			check.errorf(x, InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
   871  			return
   872  		}
   873  
   874  		y := args[1]
   875  		if !check.isValidIndex(y, InvalidUnsafeSlice, "length", false) {
   876  			return
   877  		}
   878  
   879  		x.mode = value
   880  		x.typ = NewSlice(ptr.base)
   881  		if check.recordTypes() {
   882  			check.recordBuiltinType(call.Fun, makeSig(x.typ, ptr, y.typ))
   883  		}
   884  
   885  	case _SliceData:
   886  		// unsafe.SliceData(slice []T) *T
   887  		check.verifyVersionf(call.Fun, go1_20, "unsafe.SliceData")
   888  
   889  		u, _ := commonUnder(x.typ, nil)
   890  		slice, _ := u.(*Slice)
   891  		if slice == nil {
   892  			check.errorf(x, InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
   893  			return
   894  		}
   895  
   896  		x.mode = value
   897  		x.typ = NewPointer(slice.elem)
   898  		if check.recordTypes() {
   899  			check.recordBuiltinType(call.Fun, makeSig(x.typ, slice))
   900  		}
   901  
   902  	case _String:
   903  		// unsafe.String(ptr *byte, len IntegerType) string
   904  		check.verifyVersionf(call.Fun, go1_20, "unsafe.String")
   905  
   906  		check.assignment(x, NewPointer(universeByte), "argument to unsafe.String")
   907  		if x.mode == invalid {
   908  			return
   909  		}
   910  
   911  		y := args[1]
   912  		if !check.isValidIndex(y, InvalidUnsafeString, "length", false) {
   913  			return
   914  		}
   915  
   916  		x.mode = value
   917  		x.typ = Typ[String]
   918  		if check.recordTypes() {
   919  			check.recordBuiltinType(call.Fun, makeSig(x.typ, NewPointer(universeByte), y.typ))
   920  		}
   921  
   922  	case _StringData:
   923  		// unsafe.StringData(str string) *byte
   924  		check.verifyVersionf(call.Fun, go1_20, "unsafe.StringData")
   925  
   926  		check.assignment(x, Typ[String], "argument to unsafe.StringData")
   927  		if x.mode == invalid {
   928  			return
   929  		}
   930  
   931  		x.mode = value
   932  		x.typ = NewPointer(universeByte)
   933  		if check.recordTypes() {
   934  			check.recordBuiltinType(call.Fun, makeSig(x.typ, Typ[String]))
   935  		}
   936  
   937  	case _Assert:
   938  		// assert(pred) causes a typechecker error if pred is false.
   939  		// The result of assert is the value of pred if there is no error.
   940  		// Note: assert is only available in self-test mode.
   941  		if x.mode != constant_ || !isBoolean(x.typ) {
   942  			check.errorf(x, Test, invalidArg+"%s is not a boolean constant", x)
   943  			return
   944  		}
   945  		if x.val.Kind() != constant.Bool {
   946  			check.errorf(x, Test, "internal error: value of %s should be a boolean constant", x)
   947  			return
   948  		}
   949  		if !constant.BoolVal(x.val) {
   950  			check.errorf(call, Test, "%v failed", call)
   951  			// compile-time assertion failure - safe to continue
   952  		}
   953  		// result is constant - no need to record signature
   954  
   955  	case _Trace:
   956  		// trace(x, y, z, ...) dumps the positions, expressions, and
   957  		// values of its arguments. The result of trace is the value
   958  		// of the first argument.
   959  		// Note: trace is only available in self-test mode.
   960  		// (no argument evaluated yet)
   961  		if nargs == 0 {
   962  			check.dump("%v: trace() without arguments", call.Pos())
   963  			x.mode = novalue
   964  			break
   965  		}
   966  		var t operand
   967  		x1 := x
   968  		for _, arg := range argList {
   969  			check.rawExpr(nil, x1, arg, nil, false) // permit trace for types, e.g.: new(trace(T))
   970  			check.dump("%v: %s", x1.Pos(), x1)
   971  			x1 = &t // use incoming x only for first argument
   972  		}
   973  		if x.mode == invalid {
   974  			return
   975  		}
   976  		// trace is only available in test mode - no need to record signature
   977  
   978  	default:
   979  		panic("unreachable")
   980  	}
   981  
   982  	assert(x.mode != invalid)
   983  	return true
   984  }
   985  
   986  // sliceElem returns the slice element type for a slice operand x
   987  // or a type error if x is not a slice (or a type set of slices).
   988  func sliceElem(x *operand) (Type, *typeError) {
   989  	var E Type
   990  	for _, u := range typeset(x.typ) {
   991  		s, _ := u.(*Slice)
   992  		if s == nil {
   993  			if x.isNil() {
   994  				// Printing x in this case would just print "nil".
   995  				// Special case this so we can emphasize "untyped".
   996  				return nil, typeErrorf("argument must be a slice; have untyped nil")
   997  			} else {
   998  				return nil, typeErrorf("argument must be a slice; have %s", x)
   999  			}
  1000  		}
  1001  		if E == nil {
  1002  			E = s.elem
  1003  		} else if !Identical(E, s.elem) {
  1004  			return nil, typeErrorf("mismatched slice element types %s and %s in %s", E, s.elem, x)
  1005  		}
  1006  	}
  1007  	return E, nil
  1008  }
  1009  
  1010  // hasVarSize reports if the size of type t is variable due to type parameters
  1011  // or if the type is infinitely-sized due to a cycle for which the type has not
  1012  // yet been checked.
  1013  func hasVarSize(t Type, seen map[*Named]bool) (varSized bool) {
  1014  	// Cycles are only possible through *Named types.
  1015  	// The seen map is used to detect cycles and track
  1016  	// the results of previously seen types.
  1017  	if named := asNamed(t); named != nil {
  1018  		if v, ok := seen[named]; ok {
  1019  			return v
  1020  		}
  1021  		if seen == nil {
  1022  			seen = make(map[*Named]bool)
  1023  		}
  1024  		seen[named] = true // possibly cyclic until proven otherwise
  1025  		defer func() {
  1026  			seen[named] = varSized // record final determination for named
  1027  		}()
  1028  	}
  1029  
  1030  	switch u := t.Underlying().(type) {
  1031  	case *Array:
  1032  		return hasVarSize(u.elem, seen)
  1033  	case *Struct:
  1034  		for _, f := range u.fields {
  1035  			if hasVarSize(f.typ, seen) {
  1036  				return true
  1037  			}
  1038  		}
  1039  	case *Interface:
  1040  		return isTypeParam(t)
  1041  	case *Named, *Union:
  1042  		panic("unreachable")
  1043  	}
  1044  	return false
  1045  }
  1046  
  1047  // applyTypeFunc applies f to x. If x is a type parameter,
  1048  // the result is a type parameter constrained by a new
  1049  // interface bound. The type bounds for that interface
  1050  // are computed by applying f to each of the type bounds
  1051  // of x. If any of these applications of f return nil,
  1052  // applyTypeFunc returns nil.
  1053  // If x is not a type parameter, the result is f(x).
  1054  func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
  1055  	if tp, _ := Unalias(x.typ).(*TypeParam); tp != nil {
  1056  		// Test if t satisfies the requirements for the argument
  1057  		// type and collect possible result types at the same time.
  1058  		var terms []*Term
  1059  		if !tp.is(func(t *term) bool {
  1060  			if t == nil {
  1061  				return false
  1062  			}
  1063  			if r := f(t.typ); r != nil {
  1064  				terms = append(terms, NewTerm(t.tilde, r))
  1065  				return true
  1066  			}
  1067  			return false
  1068  		}) {
  1069  			return nil
  1070  		}
  1071  
  1072  		// We can type-check this fine but we're introducing a synthetic
  1073  		// type parameter for the result. It's not clear what the API
  1074  		// implications are here. Report an error for 1.18 (see go.dev/issue/50912),
  1075  		// but continue type-checking.
  1076  		var code Code
  1077  		switch id {
  1078  		case _Real:
  1079  			code = InvalidReal
  1080  		case _Imag:
  1081  			code = InvalidImag
  1082  		case _Complex:
  1083  			code = InvalidComplex
  1084  		default:
  1085  			panic("unreachable")
  1086  		}
  1087  		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)
  1088  
  1089  		// Construct a suitable new type parameter for the result type.
  1090  		// The type parameter is placed in the current package so export/import
  1091  		// works as expected.
  1092  		tpar := NewTypeName(nopos, check.pkg, tp.obj.name, nil)
  1093  		ptyp := check.newTypeParam(tpar, NewInterfaceType(nil, []Type{NewUnion(terms)})) // assigns type to tpar as a side-effect
  1094  		ptyp.index = tp.index
  1095  
  1096  		return ptyp
  1097  	}
  1098  
  1099  	return f(x.typ)
  1100  }
  1101  
  1102  // makeSig makes a signature for the given argument and result types.
  1103  // Default types are used for untyped arguments, and res may be nil.
  1104  func makeSig(res Type, args ...Type) *Signature {
  1105  	list := make([]*Var, len(args))
  1106  	for i, param := range args {
  1107  		list[i] = NewParam(nopos, nil, "", Default(param))
  1108  	}
  1109  	params := NewTuple(list...)
  1110  	var result *Tuple
  1111  	if res != nil {
  1112  		assert(!isUntyped(res))
  1113  		result = NewTuple(newVar(ResultVar, nopos, nil, "", res))
  1114  	}
  1115  	return &Signature{params: params, results: result}
  1116  }
  1117  
  1118  // arrayPtrDeref returns A if typ is of the form *A and A is an array;
  1119  // otherwise it returns typ.
  1120  func arrayPtrDeref(typ Type) Type {
  1121  	if p, ok := Unalias(typ).(*Pointer); ok {
  1122  		if a, _ := p.base.Underlying().(*Array); a != nil {
  1123  			return a
  1124  		}
  1125  	}
  1126  	return typ
  1127  }
  1128  

View as plain text