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

View as plain text