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

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

View as plain text