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  
   387  	// A parenthesized expression is the only expression for which updateExprType
   388  	// is called recursively when old.val != nil (the only other expressions where
   389  	// updateExprType recurses are unary and binary expressions, and there we don't
   390  	// recurse if old.val != nil). Thus, if we reach here, the constant value of a
   391  	// parenthesized expression was checked already and we don't need to check it again.
   392  	// Exclude them here. This avoids duplicate errors if the constant value of such
   393  	// an expression is not representable in the new type (was go.dev/issue/82087).
   394  	if _, isParen := x.(*syntax.ParenExpr); !isParen && old.val != nil {
   395  		// If x is a constant, it must be representable as a value of typ.
   396  		c := operand{old.mode, x, old.typ, old.val, 0}
   397  		check.convertUntyped(&c, typ)
   398  		if !c.isValid() {
   399  			return
   400  		}
   401  	}
   402  
   403  	// Everything's fine, record final type and value for x.
   404  	check.recordTypeAndValue(x, old.mode, typ, old.val)
   405  }
   406  
   407  // updateExprVal updates the value of x to val.
   408  func (check *Checker) updateExprVal(x syntax.Expr, val constant.Value) {
   409  	if info, ok := check.untyped[x]; ok {
   410  		info.val = val
   411  		check.untyped[x] = info
   412  	}
   413  }
   414  
   415  // implicitTypeAndValue returns the implicit type of x when used in a context
   416  // where the target type is expected. If no such implicit conversion is
   417  // possible, it returns a nil Type and non-zero error code.
   418  //
   419  // If x is a constant operand, the returned constant.Value will be the
   420  // representation of x in this context.
   421  func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) {
   422  	if !x.isValid() || x.isTyped() || !isValid(target) {
   423  		return x.typ(), nil, 0
   424  	}
   425  	// x is untyped
   426  
   427  	if isUntyped(target) {
   428  		// both x and target are untyped
   429  		if m := maxType(x.typ(), target); m != nil {
   430  			return m, nil, 0
   431  		}
   432  		return nil, nil, InvalidUntypedConversion
   433  	}
   434  
   435  	if x.isNil() {
   436  		assert(x.isUntyped())
   437  		if hasNil(target) {
   438  			if isTypes2 {
   439  				return target, nil, 0
   440  			}
   441  			// Preserve the type of nil as UntypedNil: see go.dev/issue/13061.
   442  			return Typ[UntypedNil], nil, 0
   443  		}
   444  		return nil, nil, InvalidUntypedConversion
   445  	}
   446  
   447  	switch u := target.Underlying().(type) {
   448  	case *Basic:
   449  		if x.mode() == constant_ {
   450  			v, code := check.representation(x, u)
   451  			if code != 0 {
   452  				return nil, nil, code
   453  			}
   454  			return target, v, code
   455  		}
   456  		// Non-constant untyped values may appear as the
   457  		// result of comparisons (untyped bool), intermediate
   458  		// (delayed-checked) rhs operands of shifts, and as
   459  		// the value nil.
   460  		switch x.typ().(*Basic).kind {
   461  		case UntypedBool:
   462  			if !isBoolean(target) {
   463  				return nil, nil, InvalidUntypedConversion
   464  			}
   465  		case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
   466  			if !isNumeric(target) {
   467  				return nil, nil, InvalidUntypedConversion
   468  			}
   469  		case UntypedString:
   470  			// Non-constant untyped string values are not permitted by the spec and
   471  			// should not occur during normal typechecking passes, but this path is
   472  			// reachable via the AssignableTo API.
   473  			if !isString(target) {
   474  				return nil, nil, InvalidUntypedConversion
   475  			}
   476  		default:
   477  			return nil, nil, InvalidUntypedConversion
   478  		}
   479  	case *Interface:
   480  		if isTypeParam(target) {
   481  			if !underIs(target, func(u Type) bool {
   482  				if u == nil {
   483  					return false
   484  				}
   485  				t, _, _ := check.implicitTypeAndValue(x, u)
   486  				return t != nil
   487  			}) {
   488  				return nil, nil, InvalidUntypedConversion
   489  			}
   490  			break
   491  		}
   492  		// Update operand types to the default type rather than the target
   493  		// (interface) type: values must have concrete dynamic types.
   494  		// Untyped nil was handled upfront.
   495  		if !u.Empty() {
   496  			return nil, nil, InvalidUntypedConversion // cannot assign untyped values to non-empty interfaces
   497  		}
   498  		return Default(x.typ()), nil, 0 // default type for nil is nil
   499  	default:
   500  		return nil, nil, InvalidUntypedConversion
   501  	}
   502  	return target, nil, 0
   503  }
   504  
   505  // If switchCase is true, the operator op is ignored.
   506  func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase bool) {
   507  	// Avoid spurious errors if any of the operands has an invalid type (go.dev/issue/54405).
   508  	if !isValid(x.typ()) || !isValid(y.typ()) {
   509  		x.invalidate()
   510  		return
   511  	}
   512  
   513  	if switchCase {
   514  		op = syntax.Eql
   515  	}
   516  
   517  	errOp := x  // operand for which error is reported, if any
   518  	cause := "" // specific error cause, if any
   519  
   520  	// spec: "In any comparison, the first operand must be assignable
   521  	// to the type of the second operand, or vice versa."
   522  	code := MismatchedTypes
   523  	ok, _ := x.assignableTo(check, y.typ(), nil)
   524  	if !ok {
   525  		ok, _ = y.assignableTo(check, x.typ(), nil)
   526  	}
   527  	if !ok {
   528  		// Report the error on the 2nd operand since we only
   529  		// know after seeing the 2nd operand whether we have
   530  		// a type mismatch.
   531  		errOp = y
   532  		cause = check.sprintf("mismatched types %s and %s", x.typ(), y.typ())
   533  		goto Error
   534  	}
   535  
   536  	// check if comparison is defined for operands
   537  	code = UndefinedOp
   538  	switch op {
   539  	case syntax.Eql, syntax.Neq:
   540  		// spec: "The equality operators == and != apply to operands that are comparable."
   541  		switch {
   542  		case x.isNil() || y.isNil():
   543  			// Comparison against nil requires that the other operand type has nil.
   544  			typ := x.typ()
   545  			if x.isNil() {
   546  				typ = y.typ()
   547  			}
   548  			if !hasNil(typ) {
   549  				// This case should only be possible for "nil == nil".
   550  				// Report the error on the 2nd operand since we only
   551  				// know after seeing the 2nd operand whether we have
   552  				// an invalid comparison.
   553  				errOp = y
   554  				goto Error
   555  			}
   556  
   557  		case !Comparable(x.typ()):
   558  			errOp = x
   559  			cause = check.incomparableCause(x.typ())
   560  			goto Error
   561  
   562  		case !Comparable(y.typ()):
   563  			errOp = y
   564  			cause = check.incomparableCause(y.typ())
   565  			goto Error
   566  		}
   567  
   568  	case syntax.Lss, syntax.Leq, syntax.Gtr, syntax.Geq:
   569  		// spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
   570  		switch {
   571  		case !allOrdered(x.typ()):
   572  			errOp = x
   573  			goto Error
   574  		case !allOrdered(y.typ()):
   575  			errOp = y
   576  			goto Error
   577  		}
   578  
   579  	default:
   580  		panic("unreachable")
   581  	}
   582  
   583  	// comparison is ok
   584  	if x.mode() == constant_ && y.mode() == constant_ {
   585  		x.val = constant.MakeBool(constant.Compare(x.val, op2tok[op], y.val))
   586  		// The operands are never materialized; no need to update
   587  		// their types.
   588  	} else {
   589  		x.mode_ = value
   590  		// The operands have now their final types, which at run-
   591  		// time will be materialized. Update the expression trees.
   592  		// If the current types are untyped, the materialized type
   593  		// is the respective default type.
   594  		check.updateExprType(x.expr, Default(x.typ()), true)
   595  		check.updateExprType(y.expr, Default(y.typ()), true)
   596  	}
   597  
   598  	// spec: "Comparison operators compare two operands and yield
   599  	//        an untyped boolean value."
   600  	x.typ_ = Typ[UntypedBool]
   601  	return
   602  
   603  Error:
   604  	// We have an offending operand errOp and possibly an error cause.
   605  	if cause == "" {
   606  		if isTypeParam(x.typ()) || isTypeParam(y.typ()) {
   607  			// TODO(gri) should report the specific type causing the problem, if any
   608  			if !isTypeParam(x.typ()) {
   609  				errOp = y
   610  			}
   611  			cause = check.sprintf("type parameter %s cannot use operator %s", errOp.typ(), op)
   612  		} else {
   613  			// catch-all: neither x nor y is a type parameter
   614  			what := compositeKind(errOp.typ())
   615  			if what == "" {
   616  				what = check.sprintf("%s", errOp.typ())
   617  			}
   618  			cause = check.sprintf("operator %s not defined on %s", op, what)
   619  		}
   620  	}
   621  	if switchCase {
   622  		check.errorf(x, code, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
   623  	} else {
   624  		check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
   625  	}
   626  	x.invalidate()
   627  }
   628  
   629  // incomparableCause returns a more specific cause why typ is not comparable.
   630  // If there is no more specific cause, the result is "".
   631  func (check *Checker) incomparableCause(typ Type) string {
   632  	switch typ.Underlying().(type) {
   633  	case *Slice, *Signature, *Map:
   634  		return compositeKind(typ) + " can only be compared to nil"
   635  	}
   636  	// see if we can extract a more specific error
   637  	return comparableType(typ, true, nil).format(check)
   638  }
   639  
   640  // If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
   641  func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
   642  	// TODO(gri) This function seems overly complex. Revisit.
   643  
   644  	var xval constant.Value
   645  	if x.mode() == constant_ {
   646  		xval = constant.ToInt(x.val)
   647  	}
   648  
   649  	if allInteger(x.typ()) ||
   650  		x.isUntyped() && (xval != nil && xval.Kind() == constant.Int || xval == nil && isNumeric(x.typ())) {
   651  		// The lhs is of integer type, or it is an untyped constant
   652  		// representable as an integer, or a non-constant untyped
   653  		// numeric value. Nothing to do.
   654  	} else {
   655  		// shift has no chance
   656  		check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
   657  		x.invalidate()
   658  		return
   659  	}
   660  
   661  	// spec: "The right operand in a shift expression must have integer type
   662  	// or be an untyped constant representable by a value of type uint."
   663  
   664  	// Check that constants are representable by uint, but do not convert them
   665  	// (see also go.dev/issue/47243).
   666  	var yval constant.Value
   667  	if y.mode() == constant_ {
   668  		// Provide a good error message for negative shift counts.
   669  		yval = constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
   670  		if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
   671  			check.errorf(y, InvalidShiftCount, invalidOp+"negative shift count %s", y)
   672  			x.invalidate()
   673  			return
   674  		}
   675  
   676  		if y.isUntyped() {
   677  			// Caution: Check for representability here, rather than in the switch
   678  			// below, because isInteger includes untyped integers (was bug go.dev/issue/43697).
   679  			check.representable(y, Typ[Uint])
   680  			if !y.isValid() {
   681  				x.invalidate()
   682  				return
   683  			}
   684  		}
   685  	} else {
   686  		// Check that RHS is otherwise at least of integer type.
   687  		switch {
   688  		case y.isUntyped():
   689  			// Non-constant untyped shift counts are converted to uint
   690  			// (go.dev/issue/77117, go.dev/issue/79252, go.dev/issue/80983).
   691  			// Note: If we change our opinion on go.dev/issue/77177 and
   692  			//       decide a different type for the RHS (say int) is
   693  			//       correct, update RHStype accordingly.
   694  			RHStype := Typ[Uint]
   695  			check.convertUntyped(y, RHStype)
   696  			if !y.isValid() {
   697  				x.invalidate()
   698  				return
   699  			}
   700  			fallthrough
   701  		case allInteger(y.typ()):
   702  			if !allUnsigned(y.typ()) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
   703  				x.invalidate()
   704  				return
   705  			}
   706  		default:
   707  			check.errorf(y, InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
   708  			x.invalidate()
   709  			return
   710  		}
   711  	}
   712  
   713  	if x.mode() == constant_ {
   714  		if y.mode() == constant_ {
   715  			// if either x or y has an unknown value, the result is unknown
   716  			if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
   717  				x.val = constant.MakeUnknown()
   718  				// ensure the correct type - see comment below
   719  				if !isInteger(x.typ()) {
   720  					x.typ_ = Typ[UntypedInt]
   721  				}
   722  				return
   723  			}
   724  			// rhs must be within reasonable bounds in constant shifts
   725  			const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see go.dev/issue/44057)
   726  			s, ok := constant.Uint64Val(yval)
   727  			if !ok || s > shiftBound {
   728  				check.errorf(y, InvalidShiftCount, invalidOp+"invalid shift count %s", y)
   729  				x.invalidate()
   730  				return
   731  			}
   732  			// The lhs is representable as an integer but may not be an integer
   733  			// (e.g., 2.0, an untyped float) - this can only happen for untyped
   734  			// non-integer numeric constants. Correct the type so that the shift
   735  			// result is of integer type.
   736  			if !isInteger(x.typ()) {
   737  				x.typ_ = Typ[UntypedInt]
   738  			}
   739  			// x is a constant so xval != nil and it must be of Int kind.
   740  			x.val = constant.Shift(xval, op2tok[op], uint(s))
   741  			x.expr = e
   742  			check.overflow(x, opPos(x.expr))
   743  			return
   744  		}
   745  
   746  		// non-constant shift with constant lhs
   747  		if x.isUntyped() {
   748  			// spec: "If the left operand of a non-constant shift
   749  			// expression is an untyped constant, the type of the
   750  			// constant is what it would be if the shift expression
   751  			// were replaced by its left operand alone.".
   752  			//
   753  			// Delay operand checking until we know the final type
   754  			// by marking the lhs expression as lhs shift operand.
   755  			//
   756  			// Note 1 (subtle!): Mark info.isLhs on the unparenthesized
   757  			// expression, rather than the expression. Otherwise, in
   758  			// a case like "var _ float32 = (1 << 200) << s",
   759  			// updateExprType visits 1 << 200 (where isLhs is false)
   760  			// before (1 << 200) (where isLhs would be true) reporting
   761  			// two errors: "1 << 200 overflows float32" and "shifted
   762  			// operand must be integer". With this we only get the
   763  			// 2nd error.
   764  			//
   765  			// Note 2: Usually (in correct programs), the lhs expression
   766  			// is in the untyped map. However, it is possible to
   767  			// create incorrect programs where the same expression
   768  			// is evaluated twice (via a declaration cycle) such
   769  			// that the lhs expression type is determined in the
   770  			// first round and thus deleted from the map, and then
   771  			// not found in the second round (double insertion of
   772  			// the same expr node still just leads to one entry for
   773  			// that node, and it can only be deleted once).
   774  			// Be cautious and check for presence of entry.
   775  			// Example: var e, f = int(1<<""[f]) // go.dev/issue/11347
   776  			lhs := syntax.Unparen(x.expr) // see Note 1
   777  			if info, found := check.untyped[lhs]; found {
   778  				info.isLhs = true
   779  				check.untyped[lhs] = info
   780  			}
   781  			// keep x's type
   782  			x.mode_ = value
   783  			return
   784  		}
   785  	}
   786  
   787  	x.mode_ = value
   788  }
   789  
   790  var binaryOpPredicates opPredicates
   791  
   792  func init() {
   793  	// Setting binaryOpPredicates in init avoids declaration cycles.
   794  	binaryOpPredicates = opPredicates{
   795  		syntax.Add: allNumericOrString,
   796  		syntax.Sub: allNumeric,
   797  		syntax.Mul: allNumeric,
   798  		syntax.Div: allNumeric,
   799  		syntax.Rem: allInteger,
   800  
   801  		syntax.And:    allInteger,
   802  		syntax.Or:     allInteger,
   803  		syntax.Xor:    allInteger,
   804  		syntax.AndNot: allInteger,
   805  
   806  		syntax.AndAnd: allBoolean,
   807  		syntax.OrOr:   allBoolean,
   808  	}
   809  }
   810  
   811  // isUntypedCompLit returns whether e is directly an untyped composite literal,
   812  // without traversing parenthesis (to reflect type inference mechanics).
   813  func isUntypedCompLit(e syntax.Expr) bool {
   814  	lit, _ := e.(*syntax.CompositeLit)
   815  	return lit != nil && lit.Type == nil
   816  }
   817  
   818  // If e != nil, it must be the binary expression; it may be nil for non-constant expressions
   819  // (when invoked for an assignment operation where the binary expression is implicit).
   820  func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op syntax.Operator) {
   821  	var y operand
   822  	if isComparison(op) {
   823  		if l := isUntypedCompLit(lhs); l != isUntypedCompLit(rhs) {
   824  			// we have a direction to flow the target type for a composite literal
   825  			var T *target
   826  			if l {
   827  				// {} == cl
   828  				check.expr(nil, &y, rhs)
   829  				if y.isValid() {
   830  					T = newTarget(y.typ(), "comparison")
   831  				}
   832  				check.expr(T, x, lhs)
   833  			} else {
   834  				// cl == {}
   835  				check.expr(nil, x, lhs)
   836  				if x.isValid() {
   837  					T = newTarget(x.typ(), "comparison")
   838  				}
   839  				check.expr(T, &y, rhs)
   840  			}
   841  			goto checked
   842  		}
   843  	}
   844  
   845  	check.expr(nil, x, lhs)
   846  	check.expr(nil, &y, rhs)
   847  checked:
   848  
   849  	if !x.isValid() {
   850  		return
   851  	}
   852  	if !y.isValid() {
   853  		x.invalidate()
   854  		x.expr = y.expr
   855  		return
   856  	}
   857  
   858  	if isShift(op) {
   859  		check.shift(x, &y, e, op)
   860  		return
   861  	}
   862  
   863  	check.matchTypes(x, &y)
   864  	if !x.isValid() {
   865  		return
   866  	}
   867  
   868  	if isComparison(op) {
   869  		check.comparison(x, &y, op, false)
   870  		return
   871  	}
   872  
   873  	if !Identical(x.typ(), y.typ()) {
   874  		// only report an error if we have valid types
   875  		// (otherwise we had an error reported elsewhere already)
   876  		if isValid(x.typ()) && isValid(y.typ()) {
   877  			if e != nil {
   878  				check.errorf(e, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ(), y.typ())
   879  			} else {
   880  				check.errorf(x, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ(), y.typ())
   881  			}
   882  		}
   883  		x.invalidate()
   884  		return
   885  	}
   886  
   887  	if !check.op(binaryOpPredicates, x, op) {
   888  		x.invalidate()
   889  		return
   890  	}
   891  
   892  	if op == syntax.Div || op == syntax.Rem {
   893  		// check for zero divisor
   894  		if (x.mode() == constant_ || allInteger(x.typ())) && y.mode() == constant_ && constant.Sign(y.val) == 0 {
   895  			check.error(&y, DivByZero, invalidOp+"division by zero")
   896  			x.invalidate()
   897  			return
   898  		}
   899  
   900  		// check for divisor underflow in complex division (see go.dev/issue/20227)
   901  		if x.mode() == constant_ && y.mode() == constant_ && isComplex(x.typ()) {
   902  			re, im := constant.Real(y.val), constant.Imag(y.val)
   903  			re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
   904  			if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
   905  				check.error(&y, DivByZero, invalidOp+"division by zero")
   906  				x.invalidate()
   907  				return
   908  			}
   909  		}
   910  	}
   911  
   912  	if x.mode() == constant_ && y.mode() == constant_ {
   913  		// if either x or y has an unknown value, the result is unknown
   914  		if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
   915  			x.val = constant.MakeUnknown()
   916  			// x.typ is unchanged
   917  			return
   918  		}
   919  		// force integer division for integer operands
   920  		tok := op2tok[op]
   921  		if op == syntax.Div && isInteger(x.typ()) {
   922  			tok = token.QUO_ASSIGN
   923  		}
   924  		x.val = constant.BinaryOp(x.val, tok, y.val)
   925  		x.expr = e
   926  		check.overflow(x, opPos(x.expr))
   927  		return
   928  	}
   929  
   930  	x.mode_ = value
   931  	// x.typ is unchanged
   932  }
   933  
   934  // matchTypes attempts to convert any untyped types x and y such that they match.
   935  // If an error occurs, x.mode is set to invalid.
   936  func (check *Checker) matchTypes(x, y *operand) {
   937  	// mayConvert reports whether the operands x and y may
   938  	// possibly have matching types after converting one
   939  	// untyped operand to the type of the other.
   940  	// If mayConvert returns true, we try to convert the
   941  	// operands to each other's types, and if that fails
   942  	// we report a conversion failure.
   943  	// If mayConvert returns false, we continue without an
   944  	// attempt at conversion, and if the operand types are
   945  	// not compatible, we report a type mismatch error.
   946  	mayConvert := func(x, y *operand) bool {
   947  		// If both operands are typed, there's no need for an implicit conversion.
   948  		if x.isTyped() && y.isTyped() {
   949  			return false
   950  		}
   951  		// A numeric type can only convert to another numeric type.
   952  		if allNumeric(x.typ()) != allNumeric(y.typ()) {
   953  			return false
   954  		}
   955  		// An untyped operand may convert to its default type when paired with an empty interface
   956  		// TODO(gri) This should only matter for comparisons (the only binary operation that is
   957  		//           valid with interfaces), but in that case the assignability check should take
   958  		//           care of the conversion. Verify and possibly eliminate this extra test.
   959  		if isNonTypeParamInterface(x.typ()) || isNonTypeParamInterface(y.typ()) {
   960  			return true
   961  		}
   962  		// A boolean type can only convert to another boolean type.
   963  		if allBoolean(x.typ()) != allBoolean(y.typ()) {
   964  			return false
   965  		}
   966  		// A string type can only convert to another string type.
   967  		if allString(x.typ()) != allString(y.typ()) {
   968  			return false
   969  		}
   970  		// Untyped nil can only convert to a type that has a nil.
   971  		if x.isNil() {
   972  			return hasNil(y.typ())
   973  		}
   974  		if y.isNil() {
   975  			return hasNil(x.typ())
   976  		}
   977  		// An untyped operand cannot convert to a pointer.
   978  		// TODO(gri) generalize to type parameters
   979  		if isPointer(x.typ()) || isPointer(y.typ()) {
   980  			return false
   981  		}
   982  		return true
   983  	}
   984  
   985  	if mayConvert(x, y) {
   986  		check.convertUntyped(x, y.typ())
   987  		if !x.isValid() {
   988  			return
   989  		}
   990  		check.convertUntyped(y, x.typ())
   991  		if !y.isValid() {
   992  			x.invalidate()
   993  			return
   994  		}
   995  	}
   996  }
   997  
   998  // exprKind describes the kind of an expression; the kind
   999  // determines if an expression is valid in 'statement context'.
  1000  type exprKind int
  1001  
  1002  const (
  1003  	conversion exprKind = iota
  1004  	expression
  1005  	statement
  1006  )
  1007  
  1008  // rawExpr typechecks expression e and initializes x with the expression
  1009  // value or type. If an error occurred, x.mode is set to invalid.
  1010  // If T != nil, it holds the assignment context target type.
  1011  // If e is a generic function or function call, T is used to infer the
  1012  // type arguments for e. If e is an untyped composite literal, starting
  1013  // with Go 1.28, the type of T is used as the composite literal type
  1014  // (and the composite literal must be compatible with T).
  1015  // If allowGeneric is set, the operand type may be an uninstantiated
  1016  // parameterized type or function value.
  1017  func (check *Checker) rawExpr(T *target, x *operand, e syntax.Expr, allowGeneric bool) exprKind {
  1018  	if check.conf.Trace {
  1019  		check.trace(e.Pos(), "-- expr %s", e)
  1020  		check.indent++
  1021  		defer func() {
  1022  			check.indent--
  1023  			check.trace(e.Pos(), "=> %s", x)
  1024  		}()
  1025  	}
  1026  
  1027  	kind := check.exprInternal(T, x, e)
  1028  
  1029  	if !allowGeneric {
  1030  		check.nonGeneric(T, x)
  1031  	}
  1032  
  1033  	check.record(x)
  1034  
  1035  	return kind
  1036  }
  1037  
  1038  // If x is a generic type, or a generic function whose type arguments cannot be inferred
  1039  // from a non-nil target T, nonGeneric reports an error and invalidates x.mode and x.typ.
  1040  // Otherwise it leaves x alone.
  1041  func (check *Checker) nonGeneric(T *target, x *operand) {
  1042  	if !x.isValid() || x.mode() == novalue {
  1043  		return
  1044  	}
  1045  	var what string
  1046  	switch t := x.typ().(type) {
  1047  	case *Alias, *Named:
  1048  		if isGeneric(t) {
  1049  			what = "type"
  1050  		}
  1051  	case *Signature:
  1052  		if t.tparams != nil {
  1053  			if enableReverseTypeInference && T.sig() != nil {
  1054  				check.funcInst(T, x.Pos(), x, nil, true)
  1055  				return
  1056  			}
  1057  			what = "function"
  1058  		}
  1059  	}
  1060  	if what != "" {
  1061  		check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
  1062  		x.invalidate()
  1063  		x.typ_ = Typ[Invalid]
  1064  	}
  1065  }
  1066  
  1067  // exprInternal contains the core of type checking of expressions.
  1068  // Must only be called by rawExpr.
  1069  // (See rawExpr for an explanation of the parameters.)
  1070  func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr) exprKind {
  1071  	// make sure x has a valid state in case of bailout
  1072  	// (was go.dev/issue/5770)
  1073  	x.invalidate()
  1074  	x.typ_ = Typ[Invalid]
  1075  
  1076  	switch e := e.(type) {
  1077  	case nil:
  1078  		panic("unreachable")
  1079  
  1080  	case *syntax.BadExpr:
  1081  		goto Error // error was reported before
  1082  
  1083  	case *syntax.Name:
  1084  		check.ident(x, e, false)
  1085  
  1086  	case *syntax.DotsType:
  1087  		// dots are handled explicitly where they are valid
  1088  		check.error(e, InvalidSyntaxTree, "invalid use of ...")
  1089  		goto Error
  1090  
  1091  	case *syntax.BasicLit:
  1092  		if e.Bad {
  1093  			goto Error // error reported during parsing
  1094  		}
  1095  		check.basicLit(x, e)
  1096  		if !x.isValid() {
  1097  			goto Error
  1098  		}
  1099  
  1100  	case *syntax.FuncLit:
  1101  		check.funcLit(x, e)
  1102  		if !x.isValid() {
  1103  			goto Error
  1104  		}
  1105  
  1106  	case *syntax.CompositeLit:
  1107  		check.compositeLit(T, x, e)
  1108  		if !x.isValid() {
  1109  			goto Error
  1110  		}
  1111  
  1112  	case *syntax.ParenExpr:
  1113  		// type inference doesn't go past parentheses (target types T/U = nil)
  1114  		kind := check.rawExpr(nil, x, e.X, false)
  1115  		x.expr = e
  1116  		return kind
  1117  
  1118  	case *syntax.SelectorExpr:
  1119  		check.selector(x, e, false)
  1120  
  1121  	case *syntax.IndexExpr:
  1122  		if check.indexExpr(x, e) {
  1123  			if !enableReverseTypeInference {
  1124  				T = nil
  1125  			}
  1126  			check.funcInst(T, e.Pos(), x, e, true)
  1127  		}
  1128  		if !x.isValid() {
  1129  			goto Error
  1130  		}
  1131  
  1132  	case *syntax.SliceExpr:
  1133  		check.sliceExpr(x, e)
  1134  		if !x.isValid() {
  1135  			goto Error
  1136  		}
  1137  
  1138  	case *syntax.AssertExpr:
  1139  		check.expr(nil, x, e.X)
  1140  		if !x.isValid() {
  1141  			goto Error
  1142  		}
  1143  		// x.(type) expressions are encoded via TypeSwitchGuards
  1144  		if e.Type == nil {
  1145  			check.error(e, InvalidSyntaxTree, "invalid use of AssertExpr")
  1146  			goto Error
  1147  		}
  1148  		if isTypeParam(x.typ()) {
  1149  			check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
  1150  			goto Error
  1151  		}
  1152  		if _, ok := x.typ().Underlying().(*Interface); !ok {
  1153  			check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
  1154  			goto Error
  1155  		}
  1156  		T := check.varType(e.Type)
  1157  		if !isValid(T) {
  1158  			goto Error
  1159  		}
  1160  		// We cannot assert to an incomplete type; make sure it's complete.
  1161  		if !check.isComplete(T) {
  1162  			goto Error
  1163  		}
  1164  		check.typeAssertion(e, x, T, false)
  1165  		x.mode_ = commaok
  1166  		x.typ_ = T
  1167  
  1168  	case *syntax.TypeSwitchGuard:
  1169  		// x.(type) expressions are handled explicitly in type switches
  1170  		check.error(e, InvalidSyntaxTree, "use of .(type) outside type switch")
  1171  		check.use(e.X)
  1172  		goto Error
  1173  
  1174  	case *syntax.CallExpr:
  1175  		return check.callExpr(x, e)
  1176  
  1177  	case *syntax.ListExpr:
  1178  		// catch-all for unexpected expression lists
  1179  		check.error(e, InvalidSyntaxTree, "unexpected list of expressions")
  1180  		goto Error
  1181  
  1182  	// case *syntax.UnaryExpr:
  1183  	// 	check.expr(x, e.X)
  1184  	// 	if x.mode == invalid {
  1185  	// 		goto Error
  1186  	// 	}
  1187  	// 	check.unary(x, e, e.Op)
  1188  	// 	if x.mode == invalid {
  1189  	// 		goto Error
  1190  	// 	}
  1191  	// 	if e.Op == token.ARROW {
  1192  	// 		x.expr = e
  1193  	// 		return statement // receive operations may appear in statement context
  1194  	// 	}
  1195  
  1196  	// case *syntax.BinaryExpr:
  1197  	// 	check.binary(x, e, e.X, e.Y, e.Op)
  1198  	// 	if x.mode == invalid {
  1199  	// 		goto Error
  1200  	// 	}
  1201  
  1202  	case *syntax.Operation:
  1203  		if e.Y == nil {
  1204  			// unary expression
  1205  			if e.Op == syntax.Mul {
  1206  				// pointer indirection
  1207  				check.exprOrType(x, e.X, false)
  1208  				switch x.mode() {
  1209  				case invalid:
  1210  					goto Error
  1211  				case typexpr:
  1212  					check.validVarType(e.X, x.typ())
  1213  					x.typ_ = &Pointer{base: x.typ()}
  1214  				default:
  1215  					var base Type
  1216  					if !underIs(x.typ(), func(u Type) bool {
  1217  						p, _ := u.(*Pointer)
  1218  						if p == nil {
  1219  							check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
  1220  							return false
  1221  						}
  1222  						if base != nil && !Identical(p.base, base) {
  1223  							check.errorf(x, InvalidIndirection, invalidOp+"pointers of %s must have identical base types", x)
  1224  							return false
  1225  						}
  1226  						base = p.base
  1227  						return true
  1228  					}) {
  1229  						goto Error
  1230  					}
  1231  					// We cannot dereference a pointer with an incomplete base type; make sure it's complete.
  1232  					if !check.isComplete(base) {
  1233  						goto Error
  1234  					}
  1235  					x.mode_ = variable
  1236  					x.typ_ = base
  1237  				}
  1238  				break
  1239  			}
  1240  
  1241  			check.unary(x, e)
  1242  			if !x.isValid() {
  1243  				goto Error
  1244  			}
  1245  			if e.Op == syntax.Recv {
  1246  				x.expr = e
  1247  				return statement // receive operations may appear in statement context
  1248  			}
  1249  			break
  1250  		}
  1251  
  1252  		// binary expression
  1253  		check.binary(x, e, e.X, e.Y, e.Op)
  1254  		if !x.isValid() {
  1255  			goto Error
  1256  		}
  1257  
  1258  	case *syntax.KeyValueExpr:
  1259  		// key:value expressions are handled in composite literals
  1260  		check.error(e, InvalidSyntaxTree, "no key:value expected")
  1261  		goto Error
  1262  
  1263  	case *syntax.ArrayType, *syntax.SliceType, *syntax.StructType, *syntax.FuncType,
  1264  		*syntax.InterfaceType, *syntax.MapType, *syntax.ChanType:
  1265  		x.mode_ = typexpr
  1266  		x.typ_ = check.typ(e)
  1267  		// Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue
  1268  		// even though check.typ has already called it. This is fine as both
  1269  		// times the same expression and type are recorded. It is also not a
  1270  		// performance issue because we only reach here for composite literal
  1271  		// types, which are comparatively rare.
  1272  
  1273  	default:
  1274  		panic(fmt.Sprintf("%s: unknown expression type %T", atPos(e), e))
  1275  	}
  1276  
  1277  	// everything went well
  1278  	x.expr = e
  1279  	return expression
  1280  
  1281  Error:
  1282  	x.invalidate()
  1283  	x.expr = e
  1284  	return statement // avoid follow-up errors
  1285  }
  1286  
  1287  // typeAssertion checks x.(T). The type of x must be an interface.
  1288  func (check *Checker) typeAssertion(e syntax.Expr, x *operand, T Type, typeSwitch bool) {
  1289  	var cause string
  1290  	if check.assertableTo(x.typ(), T, &cause) {
  1291  		return // success
  1292  	}
  1293  
  1294  	if typeSwitch {
  1295  		check.errorf(e, ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
  1296  		return
  1297  	}
  1298  
  1299  	check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ(), cause)
  1300  }
  1301  
  1302  // expr typechecks expression e and initializes x with the expression value.
  1303  // If T != nil, it holds the assignment context target type.
  1304  // If e is a generic function or function call, T is used to infer the
  1305  // type arguments for e. If e is an untyped composite literal, starting
  1306  // with Go 1.28, the type of T is used as the composite literal type
  1307  // (and the composite literal must be compatible with T).
  1308  // The result must be a single value.
  1309  // If an error occurred, x.mode is set to invalid.
  1310  func (check *Checker) expr(T *target, x *operand, e syntax.Expr) {
  1311  	check.rawExpr(T, x, e, false)
  1312  	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
  1313  	check.singleValue(x)
  1314  }
  1315  
  1316  // genericExpr is like expr but the result may also be generic.
  1317  func (check *Checker) genericExpr(T *target, x *operand, e syntax.Expr) {
  1318  	check.rawExpr(T, x, e, true)
  1319  	check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
  1320  	check.singleValue(x)
  1321  }
  1322  
  1323  // multiExpr typechecks e and returns its value (or values) in list.
  1324  // If allowCommaOk is set and e is a map index, comma-ok, or comma-err
  1325  // expression, the result is a two-element list containing the value
  1326  // of e, and an untyped bool value or an error value, respectively.
  1327  // If an error occurred, list[0] is not valid.
  1328  func (check *Checker) multiExpr(e syntax.Expr, allowCommaOk bool) (list []*operand, commaOk bool) {
  1329  	var x operand
  1330  	check.rawExpr(nil, &x, e, false)
  1331  	check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
  1332  
  1333  	if t, ok := x.typ().(*Tuple); ok && x.isValid() {
  1334  		// multiple values
  1335  		list = make([]*operand, t.Len())
  1336  		for i, v := range t.vars {
  1337  			// create a dummy expression (in place of e) for better error messages
  1338  			dummy := newIdent(startPos(e), nth(i+1, "function result"))
  1339  			list[i] = &operand{mode_: value, expr: dummy, typ_: v.typ}
  1340  		}
  1341  		return
  1342  	}
  1343  
  1344  	// exactly one (possibly invalid or comma-ok) value
  1345  	list = []*operand{&x}
  1346  	if allowCommaOk && (x.mode() == mapindex || x.mode() == commaok || x.mode() == commaerr) {
  1347  		var what string = "ok value of (comma, ok) expression"
  1348  		var typ Type = Typ[UntypedBool]
  1349  		if x.mode() == commaerr {
  1350  			what = "err value of (comma, err) expression"
  1351  			typ = universeError
  1352  		}
  1353  		// create a dummy expression (in place of e) for better error messages
  1354  		dummy := newIdent(startPos(e), what)
  1355  		x2 := &operand{mode_: value, expr: dummy, typ_: typ}
  1356  		list = append(list, x2)
  1357  		commaOk = true
  1358  	}
  1359  
  1360  	return
  1361  }
  1362  
  1363  // nth returns a string of the form "nth " + what, where nth
  1364  // stands for 1st, 2nd, 3rd, 4th, etc. depending on n.
  1365  func nth(n int, what string) string {
  1366  	var ext string
  1367  	switch n {
  1368  	case 1:
  1369  		ext = "st"
  1370  	case 2:
  1371  		ext = "nd"
  1372  	case 3:
  1373  		ext = "rd"
  1374  	default:
  1375  		ext = "th"
  1376  	}
  1377  	return fmt.Sprintf("%d%s %s", n, ext, what)
  1378  }
  1379  
  1380  // exprOrType typechecks expression or type e and initializes x with the expression value or type.
  1381  // If allowGeneric is set, the operand type may be an uninstantiated parameterized type or function
  1382  // value.
  1383  // If an error occurred, x.mode is set to invalid.
  1384  func (check *Checker) exprOrType(x *operand, e syntax.Expr, allowGeneric bool) {
  1385  	check.rawExpr(nil, x, e, allowGeneric)
  1386  	check.exclude(x, 1<<novalue)
  1387  	check.singleValue(x)
  1388  }
  1389  
  1390  // exclude reports an error if x.mode is in modeset and sets x.mode to invalid.
  1391  // The modeset may contain any of 1<<novalue, 1<<builtin, 1<<typexpr.
  1392  func (check *Checker) exclude(x *operand, modeset uint) {
  1393  	if modeset&(1<<x.mode()) != 0 {
  1394  		var msg string
  1395  		var code Code
  1396  		switch x.mode() {
  1397  		case novalue:
  1398  			if modeset&(1<<typexpr) != 0 {
  1399  				msg = "%s used as value"
  1400  			} else {
  1401  				msg = "%s used as value or type"
  1402  			}
  1403  			code = TooManyValues
  1404  		case builtin:
  1405  			msg = "%s must be called"
  1406  			code = UncalledBuiltin
  1407  		case typexpr:
  1408  			msg = "%s is not an expression"
  1409  			code = NotAnExpr
  1410  		default:
  1411  			panic("unreachable")
  1412  		}
  1413  		check.errorf(x, code, msg, x)
  1414  		x.invalidate()
  1415  	}
  1416  }
  1417  
  1418  // singleValue reports an error if x describes a tuple and sets x.mode to invalid.
  1419  func (check *Checker) singleValue(x *operand) {
  1420  	if x.mode() == value {
  1421  		// tuple types are never named - no need for underlying type below
  1422  		if t, ok := x.typ().(*Tuple); ok {
  1423  			assert(t.Len() != 1)
  1424  			check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
  1425  			x.invalidate()
  1426  		}
  1427  	}
  1428  }
  1429  
  1430  // op2tok translates syntax.Operators into token.Tokens.
  1431  var op2tok = [...]token.Token{
  1432  	syntax.Def:  token.ILLEGAL,
  1433  	syntax.Not:  token.NOT,
  1434  	syntax.Recv: token.ILLEGAL,
  1435  
  1436  	syntax.OrOr:   token.LOR,
  1437  	syntax.AndAnd: token.LAND,
  1438  
  1439  	syntax.Eql: token.EQL,
  1440  	syntax.Neq: token.NEQ,
  1441  	syntax.Lss: token.LSS,
  1442  	syntax.Leq: token.LEQ,
  1443  	syntax.Gtr: token.GTR,
  1444  	syntax.Geq: token.GEQ,
  1445  
  1446  	syntax.Add: token.ADD,
  1447  	syntax.Sub: token.SUB,
  1448  	syntax.Or:  token.OR,
  1449  	syntax.Xor: token.XOR,
  1450  
  1451  	syntax.Mul:    token.MUL,
  1452  	syntax.Div:    token.QUO,
  1453  	syntax.Rem:    token.REM,
  1454  	syntax.And:    token.AND,
  1455  	syntax.AndNot: token.AND_NOT,
  1456  	syntax.Shl:    token.SHL,
  1457  	syntax.Shr:    token.SHR,
  1458  }
  1459  

View as plain text