go/types: better error message for certain unaary/binary expression errors
Fixes golang/go#11367. Change-Id: Ic7f1bad51165685097c909fd18c245a57924cdc8 Reviewed-on: https://go-review.googlesource.com/11363 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
e9a746de6e
commit
6369699504
|
@ -79,7 +79,8 @@ func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (check *Checker) unary(x *operand, op token.Token) {
|
||||
// The binary expression e may be nil. It's passed in for better error messages only.
|
||||
func (check *Checker) unary(x *operand, e *ast.UnaryExpr, op token.Token) {
|
||||
switch op {
|
||||
case token.AND:
|
||||
// spec: "As an exception to the addressability
|
||||
|
@ -126,6 +127,9 @@ func (check *Checker) unary(x *operand, op token.Token) {
|
|||
// Typed constants must be representable in
|
||||
// their type after each constant operation.
|
||||
if isTyped(typ) {
|
||||
if e != nil {
|
||||
x.expr = e // for better error message
|
||||
}
|
||||
check.representable(x, typ)
|
||||
}
|
||||
return
|
||||
|
@ -722,7 +726,8 @@ var binaryOpPredicates = opPredicates{
|
|||
token.LOR: isBoolean,
|
||||
}
|
||||
|
||||
func (check *Checker) binary(x *operand, lhs, rhs ast.Expr, op token.Token) {
|
||||
// The binary expression e may be nil. It's passed in for better error messages only.
|
||||
func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, op token.Token) {
|
||||
var y operand
|
||||
|
||||
check.expr(x, lhs)
|
||||
|
@ -788,6 +793,9 @@ func (check *Checker) binary(x *operand, lhs, rhs ast.Expr, op token.Token) {
|
|||
// Typed constants must be representable in
|
||||
// their type after each constant operation.
|
||||
if isTyped(typ) {
|
||||
if e != nil {
|
||||
x.expr = e // for better error message
|
||||
}
|
||||
check.representable(x, typ)
|
||||
}
|
||||
return
|
||||
|
@ -1375,7 +1383,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
|||
if x.mode == invalid {
|
||||
goto Error
|
||||
}
|
||||
check.unary(x, e.Op)
|
||||
check.unary(x, e, e.Op)
|
||||
if x.mode == invalid {
|
||||
goto Error
|
||||
}
|
||||
|
@ -1385,7 +1393,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
|||
}
|
||||
|
||||
case *ast.BinaryExpr:
|
||||
check.binary(x, e.X, e.Y, e.Op)
|
||||
check.binary(x, e, e.X, e.Y, e.Op)
|
||||
if x.mode == invalid {
|
||||
goto Error
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
}
|
||||
var x operand
|
||||
Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position
|
||||
check.binary(&x, s.X, Y, op)
|
||||
check.binary(&x, nil, s.X, Y, op)
|
||||
if x.mode == invalid {
|
||||
return
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
return
|
||||
}
|
||||
var x operand
|
||||
check.binary(&x, s.Lhs[0], s.Rhs[0], op)
|
||||
check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op)
|
||||
if x.mode == invalid {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -25,6 +25,12 @@ var (
|
|||
b12 = <-b0 /* ERROR "cannot receive" */
|
||||
b13 = & & /* ERROR "cannot take address" */ b0
|
||||
|
||||
// byte
|
||||
_ = byte(0)
|
||||
_ = byte(- /* ERROR "cannot convert" */ 1)
|
||||
_ = - /* ERROR "-byte\(1\) \(constant -1 of type byte\) overflows byte" */ byte(1) // test for issue 11367
|
||||
_ = byte /* ERROR "overflows byte" */ (0) - byte(1)
|
||||
|
||||
// int
|
||||
i0 = 1
|
||||
i1 int = i0
|
||||
|
|
Loading…
Reference in New Issue