mirror of https://github.com/golang/go.git
go/types, types2: use orig. compiler error message for a shift error
Slightly better for cases such as string(1 << s). Leaves type-checker tests alone for now because there are multiple dozens. For #45117. Change-Id: I47b314c713fabe424c2158674bf965416a8a6f5c Reviewed-on: https://go-review.googlesource.com/c/go/+/379274 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
a4d3c73ac3
commit
1efc5815dd
|
|
@ -504,8 +504,11 @@ func (check *Checker) invalidConversion(code errorCode, x *operand, target Type)
|
|||
// 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
|
||||
|
|
@ -548,7 +551,7 @@ func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
|
|||
// 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.
|
||||
|
|
@ -559,7 +562,7 @@ func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
|
|||
// 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 {
|
||||
|
|
@ -580,7 +583,7 @@ func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
|
|||
if old.val != nil {
|
||||
break
|
||||
}
|
||||
check.updateExprType(x.X, typ, final)
|
||||
check.updateExprType0(x, x.X, typ, final)
|
||||
break
|
||||
}
|
||||
|
||||
|
|
@ -594,11 +597,11 @@ func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
|
|||
} 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:
|
||||
|
|
@ -622,7 +625,11 @@ func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
|
|||
// 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
|
||||
|
|
|
|||
|
|
@ -472,8 +472,11 @@ func (check *Checker) invalidConversion(code errorCode, x *operand, target Type)
|
|||
// 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
|
||||
|
|
@ -515,7 +518,7 @@ func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) {
|
|||
// 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.
|
||||
|
|
@ -526,7 +529,7 @@ func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) {
|
|||
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 {
|
||||
|
|
@ -538,11 +541,11 @@ func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) {
|
|||
} 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:
|
||||
|
|
@ -566,7 +569,11 @@ func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) {
|
|||
// 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
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ package p
|
|||
import "unsafe"
|
||||
|
||||
func f() {
|
||||
_ = complex(1<<uintptr(unsafe.Pointer(nil)), 0) // ERROR "invalid operation: .*shift of type float64.*|non-integer type for left operand of shift|shifted operand .* must be integer"
|
||||
_ = complex(1<<uintptr(unsafe.Pointer(nil)), 0) // ERROR "invalid operation: .*shift of type float64.*|non-integer type for left operand of shift"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue