// 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) {
+ check.updateExprType0(nil, x, typ, final)
+}
+
+func (check *Checker) updateExprType0(parent, x syntax.Expr, typ Type, final bool) {
old, found := check.untyped[x]
if !found {
return // nothing to do
// No operands to take care of.
case *syntax.ParenExpr:
- check.updateExprType(x.X, typ, final)
+ check.updateExprType0(x, x.X, typ, final)
// case *syntax.UnaryExpr:
// // If x is a constant, the operands were constants.
// if old.val != nil {
// break
// }
- // check.updateExprType(x.X, typ, final)
+ // check.updateExprType0(x, x.X, typ, final)
case *syntax.Operation:
if x.Y == nil {
if old.val != nil {
break
}
- check.updateExprType(x.X, typ, final)
+ check.updateExprType0(x, x.X, typ, final)
break
}
} else if isShift(x.Op) {
// The result type depends only on lhs operand.
// The rhs type was updated when checking the shift.
- check.updateExprType(x.X, typ, final)
+ check.updateExprType0(x, x.X, typ, final)
} else {
// The operand types match the result type.
- check.updateExprType(x.X, typ, final)
- check.updateExprType(x.Y, typ, final)
+ check.updateExprType0(x, x.X, typ, final)
+ check.updateExprType0(x, x.Y, typ, final)
}
default:
// We already know from the shift check that it is representable
// as an integer if it is a constant.
if !allInteger(typ) {
- check.errorf(x, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
+ if check.conf.CompilerErrorMessages {
+ check.errorf(x, invalidOp+"%s (shift of type %s)", parent, typ)
+ } else {
+ check.errorf(x, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
+ }
return
}
// Even if we have an integer, if the value is a constant we
// 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 ast.Expr, typ Type, final bool) {
+ check.updateExprType0(nil, x, typ, final)
+}
+
+func (check *Checker) updateExprType0(parent, x ast.Expr, typ Type, final bool) {
old, found := check.untyped[x]
if !found {
return // nothing to do
// No operands to take care of.
case *ast.ParenExpr:
- check.updateExprType(x.X, typ, final)
+ check.updateExprType0(x, x.X, typ, final)
case *ast.UnaryExpr:
// If x is a constant, the operands were constants.
if old.val != nil {
break
}
- check.updateExprType(x.X, typ, final)
+ check.updateExprType0(x, x.X, typ, final)
case *ast.BinaryExpr:
if old.val != nil {
} else if isShift(x.Op) {
// The result type depends only on lhs operand.
// The rhs type was updated when checking the shift.
- check.updateExprType(x.X, typ, final)
+ check.updateExprType0(x, x.X, typ, final)
} else {
// The operand types match the result type.
- check.updateExprType(x.X, typ, final)
- check.updateExprType(x.Y, typ, final)
+ check.updateExprType0(x, x.X, typ, final)
+ check.updateExprType0(x, x.Y, typ, final)
}
default:
// We already know from the shift check that it is representable
// as an integer if it is a constant.
if !allInteger(typ) {
- check.invalidOp(x, _InvalidShiftOperand, "shifted operand %s (type %s) must be integer", x, typ)
+ if compilerErrorMessages {
+ check.invalidOp(x, _InvalidShiftOperand, "%s (shift of type %s)", parent, typ)
+ } else {
+ check.invalidOp(x, _InvalidShiftOperand, "shifted operand %s (type %s) must be integer", x, typ)
+ }
return
}
// Even if we have an integer, if the value is a constant we