go.tools/go/types: better error messages for invald expression statements

Also: removed some dynamic print formats.

R=adonovan
CC=golang-dev
https://golang.org/cl/13849043
This commit is contained in:
Robert Griesemer 2013-09-23 15:39:11 -07:00
parent 318b83e376
commit 0e6d095d11
3 changed files with 37 additions and 16 deletions

View File

@ -1280,7 +1280,7 @@ func (check *checker) expr0(x *operand, e ast.Expr, hint Type) exprKind {
}
if e.Op == token.ARROW {
x.expr = e
return statement // receive operators may appear in statement context
return statement // receive operations may appear in statement context
}
case *ast.BinaryExpr:
@ -1329,11 +1329,11 @@ func (check *checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface,
}
var msg string
if wrongType {
msg = "%s cannot have dynamic type %s (wrong type for method %s)"
msg = "wrong type for method"
} else {
msg = "%s cannot have dynamic type %s (missing method %s)"
msg = "missing method"
}
check.errorf(pos, msg, x, T, method.name)
check.errorf(pos, "%s cannot have dynamic type %s (%s %s)", x, T, msg, method.name)
}
// expr typechecks expression e and initializes x with the expression value.
@ -1346,13 +1346,13 @@ func (check *checker) expr(x *operand, e ast.Expr) {
default:
return
case novalue:
msg = "%s used as value"
msg = "used as value"
case builtin:
msg = "%s must be called"
msg = "must be called"
case typexpr:
msg = "%s is not an expression"
msg = "is not an expression"
}
check.errorf(x.pos(), msg, x)
check.errorf(x.pos(), "%s %s", x, msg)
x.mode = invalid
}
@ -1368,13 +1368,13 @@ func (check *checker) exprWithHint(x *operand, e ast.Expr, hint Type) {
default:
return
case novalue:
msg = "%s used as value"
msg = "used as value"
case builtin:
msg = "%s must be called"
msg = "must be called"
case typexpr:
msg = "%s is not an expression"
msg = "is not an expression"
}
check.errorf(x.pos(), msg, x)
check.errorf(x.pos(), "%s %s", x, msg)
x.mode = invalid
}

View File

@ -119,10 +119,20 @@ func (check *checker) stmt(s ast.Stmt, fallthroughOk bool) {
// function and method calls and receive operations can appear
// in statement context. Such statements may be parenthesized."
var x operand
if check.rawExpr(&x, s.X, nil) != statement {
check.errorf(s.X.Pos(), "%s is not used", s.X)
}
kind := check.rawExpr(&x, s.X, nil)
var msg string
switch x.mode {
default:
if kind == statement {
return
}
msg = "is not used"
case builtin:
msg = "must be called"
case typexpr:
msg = "is not an expression"
}
check.errorf(x.pos(), "%s %s", &x, msg)
case *ast.SendStmt:
var ch, x operand

View File

@ -468,3 +468,14 @@ func labels0() {
L2:
}
}
func expression_statements(ch chan int) {
expression_statements(ch)
<-ch
println()
0 /* ERROR "not used" */
1 /* ERROR "not used" */ +2
cap /* ERROR "not used" */ (ch)
println /* ERROR "must be called" */
}