type opPredicates … var unaryOpPredicates … func init() { … } func (check *Checker) op(m opPredicates, x *operand, op syntax.Operator) bool { … } // opPos returns the position of the operator if x is an operation; // otherwise it returns the start position of x. func opPos(x syntax.Expr) syntax.Pos { … } // opName returns the name of the operation if x is an operation // that might overflow; otherwise it returns the empty string. func opName(x syntax.Expr) string { … } var op2str1 … var op2str2 … func (check *Checker) unary(x *operand, e *syntax.Operation) { … } func isShift(op syntax.Operator) bool { … } func isComparison(op syntax.Operator) bool { … } // updateExprType updates the type of x to typ and invokes itself // recursively for the operands of x, depending on expression kind. // If typ is still an untyped and not the final type, updateExprType // only updates the recorded untyped type for x and possibly its // operands. Otherwise (i.e., typ is not an untyped type anymore, // or it is the final type for x), the type and value are recorded. // Also, if x is a constant, it must be representable as a value of typ, // and if x is the (formerly untyped) lhs operand of a non-constant // shift, it must be an integer value. func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) { … } // updateExprVal updates the value of x to val. func (check *Checker) updateExprVal(x syntax.Expr, val constant.Value) { … } // implicitTypeAndValue returns the implicit type of x when used in a context // where the target type is expected. If no such implicit conversion is // possible, it returns a nil Type and non-zero error code. // // If x is a constant operand, the returned constant.Value will be the // representation of x in this context. func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) { … } // If switchCase is true, the operator op is ignored. func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase bool) { … } // incomparableCause returns a more specific cause why typ is not comparable. // If there is no more specific cause, the result is "". func (check *Checker) incomparableCause(typ Type) string { … } // If e != nil, it must be the shift expression; it may be nil for non-constant shifts. func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) { … } var binaryOpPredicates … func init() { … } // If e != nil, it must be the binary expression; it may be nil for non-constant expressions // (when invoked for an assignment operation where the binary expression is implicit). func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op syntax.Operator) { … } // matchTypes attempts to convert any untyped types x and y such that they match. // If an error occurs, x.mode is set to invalid. func (check *Checker) matchTypes(x, y *operand) { … } type exprKind … const conversion … const expression … const statement … type target … // newTarget creates a new target for the given type and description. // The result is nil if typ is not a signature. func newTarget(typ Type, desc string) *target { … } // rawExpr typechecks expression e and initializes x with the expression // value or type. If an error occurred, x.mode is set to invalid. // If a non-nil target T is given and e is a generic function, // T is used to infer the type arguments for e. // If hint != nil, it is the type of a composite literal element. // If allowGeneric is set, the operand type may be an uninstantiated // parameterized type or function value. func (check *Checker) rawExpr(T *target, x *operand, e syntax.Expr, hint Type, allowGeneric bool) exprKind { … } // If x is a generic type, or a generic function whose type arguments cannot be inferred // from a non-nil target T, nonGeneric reports an error and invalidates x.mode and x.typ. // Otherwise it leaves x alone. func (check *Checker) nonGeneric(T *target, x *operand) { … } // exprInternal contains the core of type checking of expressions. // Must only be called by rawExpr. // (See rawExpr for an explanation of the parameters.) func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr, hint Type) exprKind { … } // keyVal maps a complex, float, integer, string or boolean constant value // to the corresponding complex128, float64, int64, uint64, string, or bool // Go value if possible; otherwise it returns x. // A complex constant that can be represented as a float (such as 1.2 + 0i) // is returned as a floating point value; if a floating point value can be // represented as an integer (such as 1.0) it is returned as an integer value. // This ensures that constants of different kind but equal value (such as // 1.0 + 0i, 1.0, 1) result in the same value. func keyVal(x constant.Value) interface{ … } // typeAssertion checks x.(T). The type of x must be an interface. func (check *Checker) typeAssertion(e syntax.Expr, x *operand, T Type, typeSwitch bool) { … } // expr typechecks expression e and initializes x with the expression value. // If a non-nil target T is given and e is a generic function or // a function call, T is used to infer the type arguments for e. // The result must be a single value. // If an error occurred, x.mode is set to invalid. func (check *Checker) expr(T *target, x *operand, e syntax.Expr) { … } // genericExpr is like expr but the result may also be generic. func (check *Checker) genericExpr(x *operand, e syntax.Expr) { … } // multiExpr typechecks e and returns its value (or values) in list. // If allowCommaOk is set and e is a map index, comma-ok, or comma-err // expression, the result is a two-element list containing the value // of e, and an untyped bool value or an error value, respectively. // If an error occurred, list[0] is not valid. func (check *Checker) multiExpr(e syntax.Expr, allowCommaOk bool) (list []*operand, commaOk bool) { … } // exprWithHint typechecks expression e and initializes x with the expression value; // hint is the type of a composite literal element. // If an error occurred, x.mode is set to invalid. func (check *Checker) exprWithHint(x *operand, e syntax.Expr, hint Type) { … } // exprOrType typechecks expression or type e and initializes x with the expression value or type. // If allowGeneric is set, the operand type may be an uninstantiated parameterized type or function // value. // If an error occurred, x.mode is set to invalid. func (check *Checker) exprOrType(x *operand, e syntax.Expr, allowGeneric bool) { … } // exclude reports an error if x.mode is in modeset and sets x.mode to invalid. // The modeset may contain any of 1<<novalue, 1<<builtin, 1<<typexpr. func (check *Checker) exclude(x *operand, modeset uint) { … } // singleValue reports an error if x describes a tuple and sets x.mode to invalid. func (check *Checker) singleValue(x *operand) { … } var op2tok …