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

View as plain text