Source file src/cmd/compile/internal/types2/expr.go

     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.
     4  
     5  // This file implements typechecking of expressions.
     6  
     7  package types2
     8  
     9  import (
    10  	"cmd/compile/internal/syntax"
    11  	"fmt"
    12  	"go/constant"
    13  	"go/token"
    14  	. "internal/types/errors"
    15  )
    16  
    17  /*
    18  Basic algorithm:
    19  
    20  Expressions are checked recursively, top down. Expression checker functions
    21  are generally of the form:
    22  
    23    func f(T *target, x *operand, e *syntax.Expr, ...)
    24  
    25  where e is the expression to be checked, T is the target type for e if
    26  e appears in an assignment context, and x is the result of the check.
    27  The check performed by f may fail in which case x.mode_ == invalid, and
    28  related error messages will have been issued by f.
    29  
    30  If T is not nil, it represents the target type expected by the context, such as
    31  the LHS variable type of an assignment, the field type of a composite literal
    32  element, etc. It is used to infer the type or type parameters missing in e.
    33  
    34  All expressions are checked via rawExpr, which dispatches according
    35  to expression kind. Upon returning, rawExpr is recording the types and
    36  constant values for all expressions that have an untyped type (those types
    37  may change on the way up in the expression tree). Usually these are constants,
    38  but the results of comparisons or non-constant shifts of untyped constants
    39  may also be untyped, but not constant.
    40  
    41  Untyped expressions may eventually become fully typed (i.e., not untyped),
    42  typically when the value is assigned to a variable, or is used otherwise.
    43  The updateExprType method is used to record this final type and update
    44  the recorded types: the type-checked expression tree is again traversed down,
    45  and the new type is propagated as needed. Untyped constant expression values
    46  that become fully typed must now be representable by the full type (constant
    47  sub-expression trees are left alone except for their roots). This mechanism
    48  ensures that a client sees the actual (run-time) type an untyped value would
    49  have. It also permits type-checking of lhs shift operands "as if the shift
    50  were not present": when updateExprType visits an untyped lhs shift operand
    51  and assigns it it's final type, that type must be an integer type, and a
    52  constant lhs must be representable as an integer.
    53  
    54  When an expression gets its final type, either on the way out from rawExpr,
    55  on the way down in updateExprType, or at the end of the type checker run,
    56  the type (and constant value, if any) is recorded via Info.Types, if present.
    57  */
    58  
    59  type opPredicates map[syntax.Operator]func(Type) bool
    60  
    61  var unaryOpPredicates opPredicates
    62  
    63  func init() {
    64  	// Setting unaryOpPredicates in init avoids declaration cycles.
    65  	unaryOpPredicates = opPredicates{
    66  		syntax.Add: allNumeric,
    67  		syntax.Sub: allNumeric,
    68  		syntax.Xor: allInteger,
    69  		syntax.Not: allBoolean,
    70  	}
    71  }
    72  
    73  func (check *Checker) op(m opPredicates, x *operand, op syntax.Operator) bool {
    74  	if pred := m[op]; pred != nil {
    75  		if !pred(x.typ()) {
    76  			check.errorf(x, UndefinedOp, invalidOp+"operator %s not defined on %s", op, x)
    77  			return false
    78  		}
    79  	} else {
    80  		check.errorf(x, InvalidSyntaxTree, "unknown operator %s", op)
    81  		return false
    82  	}
    83  	return true
    84  }
    85  
    86  // opPos returns the position of the operator if x is an operation;
    87  // otherwise it returns the start position of x.
    88  func opPos(x syntax.Expr) syntax.Pos {
    89  	switch op := x.(type) {
    90  	case nil:
    91  		return nopos // don't crash
    92  	case *syntax.Operation:
    93  		return op.Pos()
    94  	default:
    95  		return syntax.StartPos(x)
    96  	}
    97  }
    98  
    99  // opName returns the name of the operation if x is an operation
   100  // that might overflow; otherwise it returns the empty string.
   101  func opName(x syntax.Expr) string {
   102  	if e, _ := x.(*syntax.Operation); e != nil {
   103  		op := int(e.Op)
   104  		if e.Y == nil {
   105  			if op < len(op2str1) {
   106  				return op2str1[op]
   107  			}
   108  		} else {
   109  			if op < len(op2str2) {
   110  				return op2str2[op]
   111  			}
   112  		}
   113  	}
   114  	return ""
   115  }
   116  
   117  var op2str1 = [...]string{
   118  	syntax.Xor: "bitwise complement",
   119  }
   120  
   121  // This is only used for operations that may cause overflow.
   122  var op2str2 = [...]string{
   123  	syntax.Add: "addition",
   124  	syntax.Sub: "subtraction",
   125  	syntax.Xor: "bitwise XOR",
   126  	syntax.Mul: "multiplication",
   127  	syntax.Shl: "shift",
   128  }
   129  
   130  func (check *Checker) unary(x *operand, e *syntax.Operation) {
   131  	check.expr(nil, x, e.X)
   132  	if !x.isValid() {
   133  		return
   134  	}
   135  
   136  	op := e.Op
   137  	switch op {
   138  	case syntax.And:
   139  		// spec: "As an exception to the addressability
   140  		// requirement x may also be a composite literal."
   141  		if _, ok := syntax.Unparen(e.X).(*syntax.CompositeLit); !ok && x.mode() != variable {
   142  			check.errorf(x, UnaddressableOperand, invalidOp+"cannot take address of %s", x)
   143  			x.invalidate()
   144  			return
   145  		}
   146  		x.mode_ = value
   147  		x.typ_ = &Pointer{base: x.typ()}
   148  		return
   149  
   150  	case syntax.Recv:
   151  		// We cannot receive a value with an incomplete type; make sure it's complete.
   152  		if elem := check.chanElem(x, x, true); elem != nil && check.isComplete(elem) {
   153  			x.mode_ = commaok
   154  			x.typ_ = elem
   155  			check.hasCallOrRecv = true
   156  			return
   157  		}
   158  		x.invalidate()
   159  		return
   160  
   161  	case syntax.Tilde:
   162  		// Provide a better error position and message than what check.op below would do.
   163  		if !allInteger(x.typ()) {
   164  			check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
   165  			x.invalidate()
   166  			return
   167  		}
   168  		check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint (use ^ for bitwise complement)")
   169  		op = syntax.Xor
   170  	}
   171  
   172  	if !check.op(unaryOpPredicates, x, op) {
   173  		x.invalidate()
   174  		return
   175  	}
   176  
   177  	if x.mode() == constant_ {
   178  		if x.val.Kind() == constant.Unknown {
   179  			// nothing to do (and don't cause an error below in the overflow check)
   180  			return
   181  		}
   182  		var prec uint
   183  		if isUnsigned(x.typ()) {
   184  			prec = uint(check.conf.sizeof(x.typ()) * 8)
   185  		}
   186  		x.val = constant.UnaryOp(op2tok[op], x.val, prec)
   187  		x.expr = e
   188  		check.overflow(x, opPos(x.expr))
   189  		return
   190  	}
   191  
   192  	x.mode_ = value
   193  	// x.typ remains unchanged
   194  }
   195  
   196  // chanElem returns the channel element type of x for a receive from x (recv == true)
   197  // or send to x (recv == false) operation. If the operation is not valid, chanElem
   198  // reports an error and returns nil.
   199  func (check *Checker) chanElem(pos poser, x *operand, recv bool) Type {
   200  	u, err := commonUnder(x.typ(), func(t, u Type) *typeError {
   201  		if u == nil {
   202  			return typeErrorf("no specific channel type")
   203  		}
   204  		ch, _ := u.(*Chan)
   205  		if ch == nil {
   206  			return typeErrorf("non-channel %s", t)
   207  		}
   208  		if recv && ch.dir == SendOnly {
   209  			return typeErrorf("send-only channel %s", t)
   210  		}
   211  		if !recv && ch.dir == RecvOnly {
   212  			return typeErrorf("receive-only channel %s", t)
   213  		}
   214  		return nil
   215  	})
   216  
   217  	if u != nil {
   218  		return u.(*Chan).elem
   219  	}
   220  
   221  	cause := err.format(check)
   222  	if recv {
   223  		if isTypeParam(x.typ()) {
   224  			check.errorf(pos, InvalidReceive, invalidOp+"cannot receive from %s: %s", x, cause)
   225  		} else {
   226  			// In this case, only the non-channel and send-only channel error are possible.
   227  			check.errorf(pos, InvalidReceive, invalidOp+"cannot receive from %s %s", cause, x)
   228  		}
   229  	} else {
   230  		if isTypeParam(x.typ()) {
   231  			check.errorf(pos, InvalidSend, invalidOp+"cannot send to %s: %s", x, cause)
   232  		} else {
   233  			// In this case, only the non-channel and receive-only channel error are possible.
   234  			check.errorf(pos, InvalidSend, invalidOp+"cannot send to %s %s", cause, x)
   235  		}
   236  	}
   237  	return nil
   238  }
   239  
   240  func isShift(op syntax.Operator) bool {
   241  	return op == syntax.Shl || op == syntax.Shr
   242  }
   243  
   244  func isComparison(op syntax.Operator) bool {
   245  	// Note: tokens are not ordered well to make this much easier
   246  	switch op {
   247  	case syntax.Eql, syntax.Neq, syntax.Lss, syntax.Leq, syntax.Gtr, syntax.Geq:
   248  		return true
   249  	}
   250  	return false
   251  }
   252  
   253  // updateExprType updates the type of x to typ and invokes itself
   254  // recursively for the operands of x, depending on expression kind.
   255  // If typ is still an untyped and not the final type, updateExprType
   256  // only updates the recorded untyped type for x and possibly its
   257  // operands. Otherwise (i.e., typ is not an untyped type anymore,
   258  // or it is the final type for x), the type and value are recorded.
   259  // Also, if x is a constant, it must be representable as a value of typ,
   260  // and if x is the (formerly untyped) lhs operand of a non-constant
   261  // shift, it must be an integer value.
   262  func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
   263  	old, found := check.untyped[x]
   264  	if !found {
   265  		return // nothing to do
   266  	}
   267  
   268  	// update operands of x if necessary
   269  	switch x := x.(type) {
   270  	case *syntax.BadExpr,
   271  		*syntax.FuncLit,
   272  		*syntax.CompositeLit,
   273  		*syntax.IndexExpr,
   274  		*syntax.SliceExpr,
   275  		*syntax.AssertExpr,
   276  		*syntax.ListExpr,
   277  		//*syntax.StarExpr,
   278  		*syntax.KeyValueExpr,
   279  		*syntax.ArrayType,
   280  		*syntax.StructType,
   281  		*syntax.FuncType,
   282  		*syntax.InterfaceType,
   283  		*syntax.MapType,
   284  		*syntax.ChanType:
   285  		// These expression are never untyped - nothing to do.
   286  		// The respective sub-expressions got their final types
   287  		// upon assignment or use.
   288  		if debug {
   289  			check.dump("%v: found old type(%s): %s (new: %s)", atPos(x), x, old.typ, typ)
   290  			panic("unreachable")
   291  		}
   292  		return
   293  
   294  	case *syntax.CallExpr:
   295  		// Resulting in an untyped constant (e.g., built-in complex).
   296  		// The respective calls take care of calling updateExprType
   297  		// for the arguments if necessary.
   298  
   299  	case *syntax.Name, *syntax.BasicLit, *syntax.SelectorExpr:
   300  		// An identifier denoting a constant, a constant literal,
   301  		// or a qualified identifier (imported untyped constant).
   302  		// No operands to take care of.
   303  
   304  	case *syntax.ParenExpr:
   305  		check.updateExprType(x.X, typ, final)
   306  
   307  	// case *syntax.UnaryExpr:
   308  	// 	// If x is a constant, the operands were constants.
   309  	// 	// The operands don't need to be updated since they
   310  	// 	// never get "materialized" into a typed value. If
   311  	// 	// left in the untyped map, they will be processed
   312  	// 	// at the end of the type check.
   313  	// 	if old.val != nil {
   314  	// 		break
   315  	// 	}
   316  	// 	check.updateExprType(x.X, typ, final)
   317  
   318  	case *syntax.Operation:
   319  		if x.Y == nil {
   320  			// unary expression
   321  			if x.Op == syntax.Mul {
   322  				// see commented out code for StarExpr above
   323  				// TODO(gri) needs cleanup
   324  				if debug {
   325  					panic("unimplemented")
   326  				}
   327  				return
   328  			}
   329  			// If x is a constant, the operands were constants.
   330  			// The operands don't need to be updated since they
   331  			// never get "materialized" into a typed value. If
   332  			// left in the untyped map, they will be processed
   333  			// at the end of the type check.
   334  			if old.val != nil {
   335  				break
   336  			}
   337  			check.updateExprType(x.X, typ, final)
   338  			break
   339  		}
   340  
   341  		// binary expression
   342  		if old.val != nil {
   343  			break // see comment for unary expressions
   344  		}
   345  		if isComparison(x.Op) {
   346  			// The result type is independent of operand types
   347  			// and the operand types must have final types.
   348  		} else if isShift(x.Op) {
   349  			// The result type depends only on lhs operand.
   350  			// The rhs type was updated when checking the shift.
   351  			check.updateExprType(x.X, typ, final)
   352  		} else {
   353  			// The operand types match the result type.
   354  			check.updateExprType(x.X, typ, final)
   355  			check.updateExprType(x.Y, typ, final)
   356  		}
   357  
   358  	default:
   359  		panic("unreachable")
   360  	}
   361  
   362  	// If the new type is not final and still untyped, just
   363  	// update the recorded type.
   364  	if !final && isUntyped(typ) {
   365  		old.typ = typ.Underlying().(*Basic)
   366  		check.untyped[x] = old
   367  		return
   368  	}
   369  
   370  	// Otherwise we have the final (typed or untyped type).
   371  	// Remove it from the map of yet untyped expressions.
   372  	delete(check.untyped, x)
   373  
   374  	if old.isLhs {
   375  		// If x is the lhs of a shift, its final type must be integer.
   376  		// We already know from the shift check that it is representable
   377  		// as an integer if it is a constant.
   378  		if !allInteger(typ) {
   379  			check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
   380  			return
   381  		}
   382  		// Even if we have an integer, if the value is a constant we
   383  		// still must check that it is representable as the specific
   384  		// int type requested (was go.dev/issue/22969). Fall through here.
   385  	}
   386  	if old.val != nil {
   387  		// If x is a constant, it must be representable as a value of typ.
   388  		c := operand{old.mode, x, old.typ, old.val, 0}
   389  		check.convertUntyped(&c, typ)
   390  		if !c.isValid() {
   391  			return
   392  		}
   393  	}
   394  
   395  	// Everything's fine, record final type and value for x.
   396  	check.recordTypeAndValue(x, old.mode, typ, old.val)
   397  }
   398  
   399  // updateExprVal updates the value of x to val.
   400  func (check *Checker) updateExprVal(x syntax.Expr, val constant.Value) {
   401  	if info, ok := check.untyped[x]; ok {
   402  		info.val = val
   403  		check.untyped[x] = info
   404  	}
   405  }
   406  
   407  // implicitTypeAndValue returns the implicit type of x when used in a context
   408  // where the target type is expected. If no such implicit conversion is
   409  // possible, it returns a nil Type and non-zero error code.
   410  //
   411  // If x is a constant operand, the returned constant.Value will be the
   412  // representation of x in this context.
   413  func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) {
   414  	if !x.isValid() || isTyped(x.typ()) || !isValid(target) {
   415  		return x.typ(), nil, 0
   416  	}
   417  	// x is untyped
   418  
   419  	if isUntyped(target) {
   420  		// both x and target are untyped
   421  		if m := maxType(x.typ(), target); m != nil {
   422  			return m, nil, 0
   423  		}
   424  		return nil, nil, InvalidUntypedConversion
   425  	}
   426  
   427  	if x.isNil() {
   428  		assert(isUntyped(x.typ()))
   429  		if hasNil(target) {
   430  			return target, nil, 0
   431  		}
   432  		return nil, nil, InvalidUntypedConversion
   433  	}
   434  
   435  	switch u := target.Underlying().(type) {
   436  	case *Basic:
   437  		if x.mode() == constant_ {
   438  			v, code := check.representation(x, u)
   439  			if code != 0 {
   440  				return nil, nil, code
   441  			}
   442  			return target, v, code
   443  		}
   444  		// Non-constant untyped values may appear as the
   445  		// result of comparisons (untyped bool), intermediate
   446  		// (delayed-checked) rhs operands of shifts, and as
   447  		// the value nil.
   448  		switch x.typ().(*Basic).kind {
   449  		case UntypedBool:
   450  			if !isBoolean(target) {
   451  				return nil, nil, InvalidUntypedConversion
   452  			}
   453  		case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
   454  			if !isNumeric(target) {
   455  				return nil, nil, InvalidUntypedConversion
   456  			}
   457  		case UntypedString:
   458  			// Non-constant untyped string values are not permitted by the spec and
   459  			// should not occur during normal typechecking passes, but this path is
   460  			// reachable via the AssignableTo API.
   461  			if !isString(target) {
   462  				return nil, nil, InvalidUntypedConversion
   463  			}
   464  		default:
   465  			return nil, nil, InvalidUntypedConversion
   466  		}
   467  	case *Interface:
   468  		if isTypeParam(target) {
   469  			if !underIs(target, func(u Type) bool {
   470  				if u == nil {
   471  					return false
   472  				}
   473  				t, _, _ := check.implicitTypeAndValue(x, u)
   474  				return t != nil
   475  			}) {
   476  				return nil, nil, InvalidUntypedConversion
   477  			}
   478  			break
   479  		}
   480  		// Update operand types to the default type rather than the target
   481  		// (interface) type: values must have concrete dynamic types.
   482  		// Untyped nil was handled upfront.
   483  		if !u.Empty() {
   484  			return nil, nil, InvalidUntypedConversion // cannot assign untyped values to non-empty interfaces
   485  		}
   486  		return Default(x.typ()), nil, 0 // default type for nil is nil
   487  	default:
   488  		return nil, nil, InvalidUntypedConversion
   489  	}
   490  	return target, nil, 0
   491  }
   492  
   493  // If switchCase is true, the operator op is ignored.
   494  func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase bool) {
   495  	// Avoid spurious errors if any of the operands has an invalid type (go.dev/issue/54405).
   496  	if !isValid(x.typ()) || !isValid(y.typ()) {
   497  		x.invalidate()
   498  		return
   499  	}
   500  
   501  	if switchCase {
   502  		op = syntax.Eql
   503  	}
   504  
   505  	errOp := x  // operand for which error is reported, if any
   506  	cause := "" // specific error cause, if any
   507  
   508  	// spec: "In any comparison, the first operand must be assignable
   509  	// to the type of the second operand, or vice versa."
   510  	code := MismatchedTypes
   511  	ok, _ := x.assignableTo(check, y.typ(), nil)
   512  	if !ok {
   513  		ok, _ = y.assignableTo(check, x.typ(), nil)
   514  	}
   515  	if !ok {
   516  		// Report the error on the 2nd operand since we only
   517  		// know after seeing the 2nd operand whether we have
   518  		// a type mismatch.
   519  		errOp = y
   520  		cause = check.sprintf("mismatched types %s and %s", x.typ(), y.typ())
   521  		goto Error
   522  	}
   523  
   524  	// check if comparison is defined for operands
   525  	code = UndefinedOp
   526  	switch op {
   527  	case syntax.Eql, syntax.Neq:
   528  		// spec: "The equality operators == and != apply to operands that are comparable."
   529  		switch {
   530  		case x.isNil() || y.isNil():
   531  			// Comparison against nil requires that the other operand type has nil.
   532  			typ := x.typ()
   533  			if x.isNil() {
   534  				typ = y.typ()
   535  			}
   536  			if !hasNil(typ) {
   537  				// This case should only be possible for "nil == nil".
   538  				// Report the error on the 2nd operand since we only
   539  				// know after seeing the 2nd operand whether we have
   540  				// an invalid comparison.
   541  				errOp = y
   542  				goto Error
   543  			}
   544  
   545  		case !Comparable(x.typ()):
   546  			errOp = x
   547  			cause = check.incomparableCause(x.typ())
   548  			goto Error
   549  
   550  		case !Comparable(y.typ()):
   551  			errOp = y
   552  			cause = check.incomparableCause(y.typ())
   553  			goto Error
   554  		}
   555  
   556  	case syntax.Lss, syntax.Leq, syntax.Gtr, syntax.Geq:
   557  		// spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
   558  		switch {
   559  		case !allOrdered(x.typ()):
   560  			errOp = x
   561  			goto Error
   562  		case !allOrdered(y.typ()):
   563  			errOp = y
   564  			goto Error
   565  		}
   566  
   567  	default:
   568  		panic("unreachable")
   569  	}
   570  
   571  	// comparison is ok
   572  	if x.mode() == constant_ && y.mode() == constant_ {
   573  		x.val = constant.MakeBool(constant.Compare(x.val, op2tok[op], y.val))
   574  		// The operands are never materialized; no need to update
   575  		// their types.
   576  	} else {
   577  		x.mode_ = value
   578  		// The operands have now their final types, which at run-
   579  		// time will be materialized. Update the expression trees.
   580  		// If the current types are untyped, the materialized type
   581  		// is the respective default type.
   582  		check.updateExprType(x.expr, Default(x.typ()), true)
   583  		check.updateExprType(y.expr, Default(y.typ()), true)
   584  	}
   585  
   586  	// spec: "Comparison operators compare two operands and yield
   587  	//        an untyped boolean value."
   588  	x.typ_ = Typ[UntypedBool]
   589  	return
   590  
   591  Error:
   592  	// We have an offending operand errOp and possibly an error cause.
   593  	if cause == "" {
   594  		if isTypeParam(x.typ()) || isTypeParam(y.typ()) {
   595  			// TODO(gri) should report the specific type causing the problem, if any
   596  			if !isTypeParam(x.typ()) {
   597  				errOp = y
   598  			}
   599  			cause = check.sprintf("type parameter %s cannot use operator %s", errOp.typ(), op)
   600  		} else {
   601  			// catch-all: neither x nor y is a type parameter
   602  			what := compositeKind(errOp.typ())
   603  			if what == "" {
   604  				what = check.sprintf("%s", errOp.typ())
   605  			}
   606  			cause = check.sprintf("operator %s not defined on %s", op, what)
   607  		}
   608  	}
   609  	if switchCase {
   610  		check.errorf(x, code, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
   611  	} else {
   612  		check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
   613  	}
   614  	x.invalidate()
   615  }
   616  
   617  // incomparableCause returns a more specific cause why typ is not comparable.
   618  // If there is no more specific cause, the result is "".
   619  func (check *Checker) incomparableCause(typ Type) string {
   620  	switch typ.Underlying().(type) {
   621  	case *Slice, *Signature, *Map:
   622  		return compositeKind(typ) + " can only be compared to nil"
   623  	}
   624  	// see if we can extract a more specific error
   625  	return comparableType(typ, true, nil).format(check)
   626  }
   627  
   628  // If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
   629  func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
   630  	// TODO(gri) This function seems overly complex. Revisit.
   631  
   632  	var xval constant.Value
   633  	if x.mode() == constant_ {
   634  		xval = constant.ToInt(x.val)
   635  	}
   636  
   637  	if allInteger(x.typ()) || isUntyped(x.typ()) && xval != nil && xval.Kind() == constant.Int {
   638  		// The lhs is of integer type or an untyped constant representable
   639  		// as an integer. Nothing to do.
   640  	} else {
   641  		// shift has no chance
   642  		check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
   643  		x.invalidate()
   644  		return
   645  	}
   646  
   647  	// spec: "The right operand in a shift expression must have integer type
   648  	// or be an untyped constant representable by a value of type uint."
   649  
   650  	// Check that constants are representable by uint, but do not convert them
   651  	// (see also go.dev/issue/47243).
   652  	var yval constant.Value
   653  	if y.mode() == constant_ {
   654  		// Provide a good error message for negative shift counts.
   655  		yval = constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
   656  		if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
   657  			check.errorf(y, InvalidShiftCount, invalidOp+"negative shift count %s", y)
   658  			x.invalidate()
   659  			return
   660  		}
   661  
   662  		if isUntyped(y.typ()) {
   663  			// Caution: Check for representability here, rather than in the switch
   664  			// below, because isInteger includes untyped integers (was bug go.dev/issue/43697).
   665  			check.representable(y, Typ[Uint])
   666  			if !y.isValid() {
   667  				x.invalidate()
   668  				return
   669  			}
   670  		}
   671  	} else {
   672  		// Check that RHS is otherwise at least of integer type.
   673  		switch {
   674  		case allInteger(y.typ()):
   675  			if !allUnsigned(y.typ()) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
   676  				x.invalidate()
   677  				return
   678  			}
   679  		case isUntyped(y.typ()):
   680  			// This is incorrect, but preserves pre-existing behavior.
   681  			// See also go.dev/issue/47410.
   682  			check.convertUntyped(y, Typ[Uint])
   683  			if !y.isValid() {
   684  				x.invalidate()
   685  				return
   686  			}
   687  		default:
   688  			check.errorf(y, InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
   689  			x.invalidate()
   690  			return
   691  		}
   692  	}
   693  
   694  	if x.mode() == constant_ {
   695  		if y.mode() == constant_ {
   696  			// if either x or y has an unknown value, the result is unknown
   697  			if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
   698  				x.val = constant.MakeUnknown()
   699  				// ensure the correct type - see comment below
   700  				if !isInteger(x.typ()) {
   701  					x.typ_ = Typ[UntypedInt]
   702  				}
   703  				return
   704  			}
   705  			// rhs must be within reasonable bounds in constant shifts
   706  			const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see go.dev/issue/44057)
   707  			s, ok := constant.Uint64Val(yval)
   708  			if !ok || s > shiftBound {
   709  				check.errorf(y, InvalidShiftCount, invalidOp+"invalid shift count %s", y)
   710  				x.invalidate()
   711  				return
   712  			}
   713  			// The lhs is representable as an integer but may not be an integer
   714  			// (e.g., 2.0, an untyped float) - this can only happen for untyped
   715  			// non-integer numeric constants. Correct the type so that the shift
   716  			// result is of integer type.
   717  			if !isInteger(x.typ()) {
   718  				x.typ_ = Typ[UntypedInt]
   719  			}
   720  			// x is a constant so xval != nil and it must be of Int kind.
   721  			x.val = constant.Shift(xval, op2tok[op], uint(s))
   722  			x.expr = e
   723  			check.overflow(x, opPos(x.expr))
   724  			return
   725  		}
   726  
   727  		// non-constant shift with constant lhs
   728  		if isUntyped(x.typ()) {
   729  			// spec: "If the left operand of a non-constant shift
   730  			// expression is an untyped constant, the type of the
   731  			// constant is what it would be if the shift expression
   732  			// were replaced by its left operand alone.".
   733  			//
   734  			// Delay operand checking until we know the final type
   735  			// by marking the lhs expression as lhs shift operand.
   736  			//
   737  			// Usually (in correct programs), the lhs expression
   738  			// is in the untyped map. However, it is possible to
   739  			// create incorrect programs where the same expression
   740  			// is evaluated twice (via a declaration cycle) such
   741  			// that the lhs expression type is determined in the
   742  			// first round and thus deleted from the map, and then
   743  			// not found in the second round (double insertion of
   744  			// the same expr node still just leads to one entry for
   745  			// that node, and it can only be deleted once).
   746  			// Be cautious and check for presence of entry.
   747  			// Example: var e, f = int(1<<""[f]) // go.dev/issue/11347
   748  			if info, found := check.untyped[x.expr]; found {
   749  				info.isLhs = true
   750  				check.untyped[x.expr] = info
   751  			}
   752  			// keep x's type
   753  			x.mode_ = value
   754  			return
   755  		}
   756  	}
   757  
   758  	// non-constant shift - lhs must be an integer
   759  	if !allInteger(x.typ()) {
   760  		check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
   761  		x.invalidate()
   762  		return
   763  	}
   764  
   765  	x.mode_ = value
   766  }
   767  
   768  var binaryOpPredicates opPredicates
   769  
   770  func init() {
   771  	// Setting binaryOpPredicates in init avoids declaration cycles.
   772  	binaryOpPredicates = opPredicates{
   773  		syntax.Add: allNumericOrString,
   774  		syntax.Sub: allNumeric,
   775  		syntax.Mul: allNumeric,
   776  		syntax.Div: allNumeric,
   777  		syntax.Rem: allInteger,
   778  
   779  		syntax.And:    allInteger,
   780  		syntax.Or:     allInteger,
   781  		syntax.Xor:    allInteger,
   782  		syntax.AndNot: allInteger,
   783  
   784  		syntax.AndAnd: allBoolean,
   785  		syntax.OrOr:   allBoolean,
   786  	}
   787  }
   788  
   789  // If e != nil, it must be the binary expression; it may be nil for non-constant expressions
   790  // (when invoked for an assignment operation where the binary expression is implicit).
   791  func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op syntax.Operator) {
   792  	var y operand
   793  
   794  	check.expr(nil, x, lhs)
   795  	check.expr(nil, &y, rhs)
   796  
   797  	if !x.isValid() {
   798  		return
   799  	}
   800  	if !y.isValid() {
   801  		x.invalidate()
   802  		x.expr = y.expr
   803  		return
   804  	}
   805  
   806  	if isShift(op) {
   807  		check.shift(x, &y, e, op)
   808  		return
   809  	}
   810  
   811  	check.matchTypes(x, &y)
   812  	if !x.isValid() {
   813  		return
   814  	}
   815  
   816  	if isComparison(op) {
   817  		check.comparison(x, &y, op, false)
   818  		return
   819  	}
   820  
   821  	if !Identical(x.typ(), y.typ()) {
   822  		// only report an error if we have valid types
   823  		// (otherwise we had an error reported elsewhere already)
   824  		if isValid(x.typ()) && isValid(y.typ()) {
   825  			if e != nil {
   826  				check.errorf(x, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ(), y.typ())
   827  			} else {
   828  				check.errorf(x, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ(), y.typ())
   829  			}
   830  		}
   831  		x.invalidate()
   832  		return
   833  	}
   834  
   835  	if !check.op(binaryOpPredicates, x, op) {
   836  		x.invalidate()
   837  		return
   838  	}
   839  
   840  	if op == syntax.Div || op == syntax.Rem {
   841  		// check for zero divisor
   842  		if (x.mode() == constant_ || allInteger(x.typ())) && y.mode() == constant_ && constant.Sign(y.val) == 0 {
   843  			check.error(&y, DivByZero, invalidOp+"division by zero")
   844  			x.invalidate()
   845  			return
   846  		}
   847  
   848  		// check for divisor underflow in complex division (see go.dev/issue/20227)
   849  		if x.mode() == constant_ && y.mode() == constant_ && isComplex(x.typ()) {
   850  			re, im := constant.Real(y.val), constant.Imag(y.val)
   851  			re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
   852  			if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
   853  				check.error(&y, DivByZero, invalidOp+"division by zero")
   854  				x.invalidate()
   855  				return
   856  			}
   857  		}
   858  	}
   859  
   860  	if x.mode() == constant_ && y.mode() == constant_ {
   861  		// if either x or y has an unknown value, the result is unknown
   862  		if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
   863  			x.val = constant.MakeUnknown()
   864  			// x.typ is unchanged
   865  			return
   866  		}
   867  		// force integer division for integer operands
   868  		tok := op2tok[op]
   869  		if op == syntax.Div && isInteger(x.typ()) {
   870  			tok = token.QUO_ASSIGN
   871  		}
   872  		x.val = constant.BinaryOp(x.val, tok, y.val)
   873  		x.expr = e
   874  		check.overflow(x, opPos(x.expr))
   875  		return
   876  	}
   877  
   878  	x.mode_ = value
   879  	// x.typ is unchanged
   880  }
   881  
   882  // matchTypes attempts to convert any untyped types x and y such that they match.
   883  // If an error occurs, x.mode is set to invalid.
   884  func (check *Checker) matchTypes(x, y *operand) {
   885  	// mayConvert reports whether the operands x and y may
   886  	// possibly have matching types after converting one
   887  	// untyped operand to the type of the other.
   888  	// If mayConvert returns true, we try to convert the
   889  	// operands to each other's types, and if that fails
   890  	// we report a conversion failure.
   891  	// If mayConvert returns false, we continue without an
   892  	// attempt at conversion, and if the operand types are
   893  	// not compatible, we report a type mismatch error.
   894  	mayConvert := func(x, y *operand) bool {
   895  		// If both operands are typed, there's no need for an implicit conversion.
   896  		if isTyped(x.typ()) && isTyped(y.typ()) {
   897  			return false
   898  		}
   899  		// A numeric type can only convert to another numeric type.
   900  		if allNumeric(x.typ()) != allNumeric(y.typ()) {
   901  			return false
   902  		}
   903  		// An untyped operand may convert to its default type when paired with an empty interface
   904  		// TODO(gri) This should only matter for comparisons (the only binary operation that is
   905  		//           valid with interfaces), but in that case the assignability check should take
   906  		//           care of the conversion. Verify and possibly eliminate this extra test.
   907  		if isNonTypeParamInterface(x.typ()) || isNonTypeParamInterface(y.typ()) {
   908  			return true
   909  		}
   910  		// A boolean type can only convert to another boolean type.
   911  		if allBoolean(x.typ()) != allBoolean(y.typ()) {
   912  			return false
   913  		}
   914  		// A string type can only convert to another string type.
   915  		if allString(x.typ()) != allString(y.typ()) {
   916  			return false
   917  		}
   918  		// Untyped nil can only convert to a type that has a nil.
   919  		if x.isNil() {
   920  			return hasNil(y.typ())
   921  		}
   922  		if y.isNil() {
   923  			return hasNil(x.typ())
   924  		}
   925  		// An untyped operand cannot convert to a pointer.
   926  		// TODO(gri) generalize to type parameters
   927  		if isPointer(x.typ()) || isPointer(y.typ()) {
   928  			return false
   929  		}
   930  		return true
   931  	}
   932  
   933  	if mayConvert(x, y) {
   934  		check.convertUntyped(x, y.typ())
   935  		if !x.isValid() {
   936  			return
   937  		}
   938  		check.convertUntyped(y, x.typ())
   939  		if !y.isValid() {
   940  			x.invalidate()
   941  			return
   942  		}
   943  	}
   944  }
   945  
   946  // exprKind describes the kind of an expression; the kind
   947  // determines if an expression is valid in 'statement context'.
   948  type exprKind int
   949  
   950  const (
   951  	conversion exprKind = iota
   952  	expression
   953  	statement
   954  )
   955  
   956  // target represents the target type in an assignment context.
   957  type target struct {
   958  	typ Type
   959  	// TODO(gri) desc is only used in Checker.funcInst - do we need it?
   960  	//           (setting/computing desc may be expensive for not being used)
   961  	//           Also, if we keep it, review consistency of description.
   962  	desc string
   963  	hint bool // if set, the target may be used as untyped composite literal hint before Go 1.28
   964  }
   965  
   966  // newTarget creates a new target for the given type and description.
   967  // The result is nil if typ is nil.
   968  func newTarget(typ Type, desc string) *target {
   969  	if typ != nil {
   970  		return &target{typ, desc, false}
   971  	}
   972  	return nil
   973  }
   974  
   975  // newHint is like newTarget but it marks the result as a hint.
   976  func newHint(typ Type, desc string) *target {
   977  	if typ != nil {
   978  		return &target{typ, desc, true}
   979  	}
   980  	return nil
   981  }
   982  
   983  // sig returns the target type T if it is a signature (the result may be its Named or Alias type, if any).
   984  // The result is nil if T is nil or T's type set has no common signature type.
   985  func (T *target) sig() Type {
   986  	if T != nil {
   987  		if u, _ := commonUnder(T.typ, nil); u != nil {
   988  			if _, ok := u.(*Signature); ok {
   989  				return T.typ
   990  			}
   991  		}
   992  	}
   993  	return nil
   994  }
   995  
   996  // String returns a string representation of T, for debugging.
   997  func (T *target) String() string {
   998  	if T != nil {
   999  		return sprintf(nil, true, "target{%s, %q}", T.typ, T.desc)
  1000  	}
  1001  	return "no target"
  1002  }
  1003  
  1004  // rawExpr typechecks expression e and initializes x with the expression
  1005  // value or type. If an error occurred, x.mode is set to invalid.
  1006  // If T != nil, it holds the assignment context target type.
  1007  // If e is a generic function or function call, T is used to infer the
  1008  // type arguments for e. If e is an untyped composite literal, starting
  1009  // with Go 1.28, the type of T is used as the composite literal type
  1010  // (and the composite literal must be compatible with T).
  1011  // If allowGeneric is set, the operand type may be an uninstantiated
  1012  // parameterized type or function value.
  1013  func (check *Checker) rawExpr(T *target, x *operand, e syntax.Expr, allowGeneric bool) exprKind {
  1014  	if check.conf.Trace {
  1015  		check.trace(e.Pos(), "-- expr %s", e)
  1016  		check.indent++
  1017  		defer func() {
  1018  			check.indent--
  1019  			check.trace(e.Pos(), "=> %s", x)
  1020  		}()
  1021  	}
  1022  
  1023  	kind := check.exprInternal(T, x, e)
  1024  
  1025  	if !allowGeneric {
  1026  		check.nonGeneric(T, x)
  1027  	}
  1028  
  1029  	check.record(x)
  1030  
  1031  	return kind
  1032  }
  1033  
  1034  // If x is a generic type, or a generic function whose type arguments cannot be inferred
  1035  // from a non-nil target T, nonGeneric reports an error and invalidates x.mode and x.typ.
  1036  // Otherwise it leaves x alone.
  1037  func (check *Checker) nonGeneric(T *target, x *operand) {
  1038  	if !x.isValid() || x.mode() == novalue {
  1039  		return
  1040  	}
  1041  	var what string
  1042  	switch t := x.typ().(type) {
  1043  	case *Alias, *Named:
  1044  		if isGeneric(t) {
  1045  			what = "type"
  1046  		}
  1047  	case *Signature:
  1048  		if t.tparams != nil {
  1049  			if enableReverseTypeInference && T.sig() != nil {
  1050  				check.funcInst(T, x.Pos(), x, nil, true)
  1051  				return
  1052  			}
  1053  			what = "function"
  1054  		}
  1055  	}
  1056  	if what != "" {
  1057  		check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
  1058  		x.invalidate()
  1059  		x.typ_ = Typ[Invalid]
  1060  	}
  1061  }
  1062  
  1063  // exprInternal contains the core of type checking of expressions.
  1064  // Must only be called by rawExpr.
  1065  // (See rawExpr for an explanation of the parameters.)
  1066  func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr) exprKind {
  1067  	// make sure x has a valid state in case of bailout
  1068  	// (was go.dev/issue/5770)
  1069  	x.invalidate()
  1070  	x.typ_ = Typ[Invalid]
  1071  
  1072  	switch e := e.(type) {
  1073  	case nil:
  1074  		panic("unreachable")
  1075  
  1076  	case *syntax.BadExpr:
  1077  		goto Error // error was reported before
  1078  
  1079  	case *syntax.Name:
  1080  		check.ident(x, e, false)
  1081  
  1082  	case *syntax.DotsType:
  1083  		// dots are handled explicitly where they are valid
  1084  		check.error(e, InvalidSyntaxTree, "invalid use of ...")
  1085  		goto Error
  1086  
  1087  	case *syntax.BasicLit:
  1088  		if e.Bad {
  1089  			goto Error // error reported during parsing
  1090  		}
  1091  		check.basicLit(x, e)
  1092  		if !x.isValid() {
  1093  			goto Error
  1094  		}
  1095  
  1096  	case *syntax.FuncLit:
  1097  		check.funcLit(x, e)
  1098  		if !x.isValid() {
  1099  			goto Error
  1100  		}
  1101  
  1102  	case *syntax.CompositeLit:
  1103  		check.compositeLit(T, x, e)
  1104  		if !x.isValid() {
  1105  			goto Error
  1106  		}
  1107  
  1108  	case *syntax.ParenExpr:
  1109  		// type inference doesn't go past parentheses (target types T/U = nil)
  1110  		kind := check.rawExpr(nil, x, e.X, false)
  1111  		x.expr = e
  1112  		return kind
  1113  
  1114  	case *syntax.SelectorExpr:
  1115  		check.selector(x, e, false)
  1116  
  1117  	case *syntax.IndexExpr:
  1118  		if check.indexExpr(x, e) {
  1119  			if !enableReverseTypeInference {
  1120  				T = nil
  1121  			}
  1122  			check.funcInst(T, e.Pos(), x, e, true)
  1123  		}
  1124  		if !x.isValid() {
  1125  			goto Error
  1126  		}
  1127  
  1128  	case *syntax.SliceExpr:
  1129  		check.sliceExpr(x, e)
  1130  		if !x.isValid() {
  1131  			goto Error
  1132  		}
  1133  
  1134  	case *syntax.AssertExpr:
  1135  		check.expr(nil, x, e.X)
  1136  		if !x.isValid() {
  1137  			goto Error
  1138  		}
  1139  		// x.(type) expressions are encoded via TypeSwitchGuards
  1140  		if e.Type == nil {
  1141  			check.error(e, InvalidSyntaxTree, "invalid use of AssertExpr")
  1142  			goto Error
  1143  		}
  1144  		if isTypeParam(x.typ()) {
  1145  			check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
  1146  			goto Error
  1147  		}
  1148  		if _, ok := x.typ().Underlying().(*Interface); !ok {
  1149  			check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
  1150  			goto Error
  1151  		}
  1152  		T := check.varType(e.Type)
  1153  		if !isValid(T) {
  1154  			goto Error
  1155  		}
  1156  		// We cannot assert to an incomplete type; make sure it's complete.
  1157  		if !check.isComplete(T) {
  1158  			goto Error
  1159  		}
  1160  		check.typeAssertion(e, x, T, false)
  1161  		x.mode_ = commaok
  1162  		x.typ_ = T
  1163  
  1164  	case *syntax.TypeSwitchGuard:
  1165  		// x.(type) expressions are handled explicitly in type switches
  1166  		check.error(e, InvalidSyntaxTree, "use of .(type) outside type switch")
  1167  		check.use(e.X)
  1168  		goto Error
  1169  
  1170  	case *syntax.CallExpr:
  1171  		return check.callExpr(x, e)
  1172  
  1173  	case *syntax.ListExpr:
  1174  		// catch-all for unexpected expression lists
  1175  		check.error(e, InvalidSyntaxTree, "unexpected list of expressions")
  1176  		goto Error
  1177  
  1178  	// case *syntax.UnaryExpr:
  1179  	// 	check.expr(x, e.X)
  1180  	// 	if x.mode == invalid {
  1181  	// 		goto Error
  1182  	// 	}
  1183  	// 	check.unary(x, e, e.Op)
  1184  	// 	if x.mode == invalid {
  1185  	// 		goto Error
  1186  	// 	}
  1187  	// 	if e.Op == token.ARROW {
  1188  	// 		x.expr = e
  1189  	// 		return statement // receive operations may appear in statement context
  1190  	// 	}
  1191  
  1192  	// case *syntax.BinaryExpr:
  1193  	// 	check.binary(x, e, e.X, e.Y, e.Op)
  1194  	// 	if x.mode == invalid {
  1195  	// 		goto Error
  1196  	// 	}
  1197  
  1198  	case *syntax.Operation:
  1199  		if e.Y == nil {
  1200  			// unary expression
  1201  			if e.Op == syntax.Mul {
  1202  				// pointer indirection
  1203  				check.exprOrType(x, e.X, false)
  1204  				switch x.mode() {
  1205  				case invalid:
  1206  					goto Error
  1207  				case typexpr:
  1208  					check.validVarType(e.X, x.typ())
  1209  					x.typ_ = &Pointer{base: x.typ()}
  1210  				default:
  1211  					var base Type
  1212  					if !underIs(x.typ(), func(u Type) bool {
  1213  						p, _ := u.(*Pointer)
  1214  						if p == nil {
  1215  							check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
  1216  							return false
  1217  						}
  1218  						if base != nil && !Identical(p.base, base) {
  1219  							check.errorf(x, InvalidIndirection, invalidOp+"pointers of %s must have identical base types", x)
  1220  							return false
  1221  						}
  1222  						base = p.base
  1223  						return true
  1224  					}) {
  1225  						goto Error
  1226  					}
  1227  					// We cannot dereference a pointer with an incomplete base type; make sure it's complete.
  1228  					if !check.isComplete(base) {
  1229  						goto Error
  1230  					}
  1231  					x.mode_ = variable
  1232  					x.typ_ = base
  1233  				}
  1234  				break
  1235  			}
  1236  
  1237  			check.unary(x, e)
  1238  			if !x.isValid() {
  1239  				goto Error
  1240  			}
  1241  			if e.Op == syntax.Recv {
  1242  				x.expr = e
  1243  				return statement // receive operations may appear in statement context
  1244  			}
  1245  			break
  1246  		}
  1247  
  1248  		// binary expression
  1249  		check.binary(x, e, e.X, e.Y, e.Op)
  1250  		if !x.isValid() {
  1251  			goto Error
  1252  		}
  1253  
  1254  	case *syntax.KeyValueExpr:
  1255  		// key:value expressions are handled in composite literals
  1256  		check.error(e, InvalidSyntaxTree, "no key:value expected")
  1257  		goto Error
  1258  
  1259  	case *syntax.ArrayType, *syntax.SliceType, *syntax.StructType, *syntax.FuncType,
  1260  		*syntax.InterfaceType, *syntax.MapType, *syntax.ChanType:
  1261  		x.mode_ = typexpr
  1262  		x.typ_ = check.typ(e)
  1263  		// Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue
  1264  		// even though check.typ has already called it. This is fine as both
  1265  		// times the same expression and type are recorded. It is also not a
  1266  		// performance issue because we only reach here for composite literal
  1267  		// types, which are comparatively rare.
  1268  
  1269  	default:
  1270  		panic(fmt.Sprintf("%s: unknown expression type %T", atPos(e), e))
  1271  	}
  1272  
  1273  	// everything went well
  1274  	x.expr = e
  1275  	return expression
  1276  
  1277  Error:
  1278  	x.invalidate()
  1279  	x.expr = e
  1280  	return statement // avoid follow-up errors
  1281  }
  1282  
  1283  // keyVal maps a complex, float, integer, string or boolean constant value
  1284  // to the corresponding complex128, float64, int64, uint64, string, or bool
  1285  // Go value if possible; otherwise it returns x.
  1286  // A complex constant that can be represented as a float (such as 1.2 + 0i)
  1287  // is returned as a floating point value; if a floating point value can be
  1288  // represented as an integer (such as 1.0) it is returned as an integer value.
  1289  // This ensures that constants of different kind but equal value (such as
  1290  // 1.0 + 0i, 1.0, 1) result in the same value.
  1291  func keyVal(x constant.Value) any {
  1292  	switch x.Kind() {
  1293  	case constant.Complex:
  1294  		f := constant.ToFloat(x)
  1295  		if f.Kind() != constant.Float {
  1296  			r, _ := constant.Float64Val(constant.Real(x))
  1297  			i, _ := constant.Float64Val(constant.Imag(x))
  1298  			return complex(r, i)
  1299  		}
  1300  		x = f
  1301  		fallthrough
  1302  	case constant.Float:
  1303  		i := constant.ToInt(x)
  1304  		if i.Kind() != constant.Int {
  1305  			v, _ := constant.Float64Val(x)
  1306  			return v
  1307  		}
  1308  		x = i
  1309  		fallthrough
  1310  	case constant.Int:
  1311  		if v, ok := constant.Int64Val(x); ok {
  1312  			return v
  1313  		}
  1314  		if v, ok := constant.Uint64Val(x); ok {
  1315  			return v
  1316  		}
  1317  	case constant.String:
  1318  		return constant.StringVal(x)
  1319  	case constant.Bool:
  1320  		return constant.BoolVal(x)
  1321  	}
  1322  	return x
  1323  }
  1324  
  1325  // typeAssertion checks x.(T). The type of x must be an interface.
  1326  func (check *Checker) typeAssertion(e syntax.Expr, x *operand, T Type, typeSwitch bool) {
  1327  	var cause string
  1328  	if check.assertableTo(x.typ(), T, &cause) {
  1329  		return // success
  1330  	}
  1331  
  1332  	if typeSwitch {
  1333  		check.errorf(e, ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
  1334  		return
  1335  	}
  1336  
  1337  	check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ(), cause)
  1338  }
  1339  
  1340  // expr typechecks expression e and initializes x with the expression value.
  1341  // If T != nil, it holds the assignment context target type.
  1342  // If e is a generic function or function call, T is used to infer the
  1343  // type arguments for e. If e is an untyped composite literal, starting
  1344  // with Go 1.28, the type of T is used as the composite literal type
  1345  // (and the composite literal must be compatible with T).
  1346  // The result must be a single value.
  1347  // If an error occurred, x.mode is set to invalid.
  1348  func (check *Checker) expr(T *target, x *operand, e syntax.Expr) {
  1349  	check.rawExpr(T, x, e, false)
  1350  	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
  1351  	check.singleValue(x)
  1352  }
  1353  
  1354  // genericExpr is like expr but the result may also be generic.
  1355  func (check *Checker) genericExpr(T *target, x *operand, e syntax.Expr) {
  1356  	check.rawExpr(T, x, e, true)
  1357  	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
  1358  	check.singleValue(x)
  1359  }
  1360  
  1361  // multiExpr typechecks e and returns its value (or values) in list.
  1362  // If allowCommaOk is set and e is a map index, comma-ok, or comma-err
  1363  // expression, the result is a two-element list containing the value
  1364  // of e, and an untyped bool value or an error value, respectively.
  1365  // If an error occurred, list[0] is not valid.
  1366  func (check *Checker) multiExpr(e syntax.Expr, allowCommaOk bool) (list []*operand, commaOk bool) {
  1367  	var x operand
  1368  	check.rawExpr(nil, &x, e, false)
  1369  	check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
  1370  
  1371  	if t, ok := x.typ().(*Tuple); ok && x.isValid() {
  1372  		// multiple values
  1373  		list = make([]*operand, t.Len())
  1374  		for i, v := range t.vars {
  1375  			// create a dummy expression (in place of e) for better error messages
  1376  			dummy := syntax.NewName(syntax.StartPos(e), nth(i+1, "function result"))
  1377  			list[i] = &operand{mode_: value, expr: dummy, typ_: v.typ}
  1378  		}
  1379  		return
  1380  	}
  1381  
  1382  	// exactly one (possibly invalid or comma-ok) value
  1383  	list = []*operand{&x}
  1384  	if allowCommaOk && (x.mode() == mapindex || x.mode() == commaok || x.mode() == commaerr) {
  1385  		var what string = "ok value of (comma, ok) expression"
  1386  		var typ Type = Typ[UntypedBool]
  1387  		if x.mode() == commaerr {
  1388  			what = "err value of (comma, err) expression"
  1389  			typ = universeError
  1390  		}
  1391  		// create a dummy expression (in place of e) for better error messages
  1392  		dummy := syntax.NewName(syntax.StartPos(e), what)
  1393  		x2 := &operand{mode_: value, expr: dummy, typ_: typ}
  1394  		list = append(list, x2)
  1395  		commaOk = true
  1396  	}
  1397  
  1398  	return
  1399  }
  1400  
  1401  // nth returns a string of the form "nth " + what, where nth
  1402  // stands for 1st, 2nd, 3rd, 4th, etc. depending on n.
  1403  func nth(n int, what string) string {
  1404  	var ext string
  1405  	switch n {
  1406  	case 1:
  1407  		ext = "st"
  1408  	case 2:
  1409  		ext = "nd"
  1410  	case 3:
  1411  		ext = "rd"
  1412  	default:
  1413  		ext = "th"
  1414  	}
  1415  	return fmt.Sprintf("%d%s %s", n, ext, what)
  1416  }
  1417  
  1418  // exprOrType typechecks expression or type e and initializes x with the expression value or type.
  1419  // If allowGeneric is set, the operand type may be an uninstantiated parameterized type or function
  1420  // value.
  1421  // If an error occurred, x.mode is set to invalid.
  1422  func (check *Checker) exprOrType(x *operand, e syntax.Expr, allowGeneric bool) {
  1423  	check.rawExpr(nil, x, e, allowGeneric)
  1424  	check.exclude(x, 1<<novalue)
  1425  	check.singleValue(x)
  1426  }
  1427  
  1428  // exclude reports an error if x.mode is in modeset and sets x.mode to invalid.
  1429  // The modeset may contain any of 1<<novalue, 1<<builtin, 1<<typexpr.
  1430  func (check *Checker) exclude(x *operand, modeset uint) {
  1431  	if modeset&(1<<x.mode()) != 0 {
  1432  		var msg string
  1433  		var code Code
  1434  		switch x.mode() {
  1435  		case novalue:
  1436  			if modeset&(1<<typexpr) != 0 {
  1437  				msg = "%s used as value"
  1438  			} else {
  1439  				msg = "%s used as value or type"
  1440  			}
  1441  			code = TooManyValues
  1442  		case builtin:
  1443  			msg = "%s must be called"
  1444  			code = UncalledBuiltin
  1445  		case typexpr:
  1446  			msg = "%s is not an expression"
  1447  			code = NotAnExpr
  1448  		default:
  1449  			panic("unreachable")
  1450  		}
  1451  		check.errorf(x, code, msg, x)
  1452  		x.invalidate()
  1453  	}
  1454  }
  1455  
  1456  // singleValue reports an error if x describes a tuple and sets x.mode to invalid.
  1457  func (check *Checker) singleValue(x *operand) {
  1458  	if x.mode() == value {
  1459  		// tuple types are never named - no need for underlying type below
  1460  		if t, ok := x.typ().(*Tuple); ok {
  1461  			assert(t.Len() != 1)
  1462  			check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
  1463  			x.invalidate()
  1464  		}
  1465  	}
  1466  }
  1467  
  1468  // op2tok translates syntax.Operators into token.Tokens.
  1469  var op2tok = [...]token.Token{
  1470  	syntax.Def:  token.ILLEGAL,
  1471  	syntax.Not:  token.NOT,
  1472  	syntax.Recv: token.ILLEGAL,
  1473  
  1474  	syntax.OrOr:   token.LOR,
  1475  	syntax.AndAnd: token.LAND,
  1476  
  1477  	syntax.Eql: token.EQL,
  1478  	syntax.Neq: token.NEQ,
  1479  	syntax.Lss: token.LSS,
  1480  	syntax.Leq: token.LEQ,
  1481  	syntax.Gtr: token.GTR,
  1482  	syntax.Geq: token.GEQ,
  1483  
  1484  	syntax.Add: token.ADD,
  1485  	syntax.Sub: token.SUB,
  1486  	syntax.Or:  token.OR,
  1487  	syntax.Xor: token.XOR,
  1488  
  1489  	syntax.Mul:    token.MUL,
  1490  	syntax.Div:    token.QUO,
  1491  	syntax.Rem:    token.REM,
  1492  	syntax.And:    token.AND,
  1493  	syntax.AndNot: token.AND_NOT,
  1494  	syntax.Shl:    token.SHL,
  1495  	syntax.Shr:    token.SHR,
  1496  }
  1497  

View as plain text