1
0
mirror of https://github.com/golang/go synced 2024-11-18 22:04:43 -07:00

go.tools/go/types: avoid spurious "declared but not used" errors in case of other errors

LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/76810044
This commit is contained in:
Robert Griesemer 2014-03-20 11:28:26 -07:00
parent a4491f08bf
commit a781b00b0d
6 changed files with 34 additions and 8 deletions

View File

@ -210,12 +210,13 @@ func (check *checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos)
l := len(lhs)
get, r, commaOk := unpack(func(x *operand, i int) { check.expr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid())
if l != r {
// invalidate lhs
// invalidate lhs and use rhs
for _, obj := range lhs {
if obj.typ == nil {
obj.typ = Typ[Invalid]
}
}
check.use(rhs...)
if returnPos.IsValid() {
check.errorf(returnPos, "wrong number of return values (want %d, got %d)", l, r)
return
@ -246,6 +247,7 @@ func (check *checker) assignVars(lhs, rhs []ast.Expr) {
get, r, commaOk := unpack(func(x *operand, i int) { check.expr(x, rhs[i]) }, len(rhs), l == 2)
if l != r {
check.errorf(rhs[0].Pos(), "assignment count mismatch (%d vs %d)", l, r)
check.use(rhs...)
return
}

View File

@ -23,7 +23,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
bin := predeclaredFuncs[id]
if call.Ellipsis.IsValid() && id != _Append {
check.invalidOp(call.Ellipsis, "invalid use of ... with built-in %s", bin.name)
check.use(call.Args)
check.use(call.Args...)
return
}
@ -481,7 +481,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
selx, _ := unparen(arg0).(*ast.SelectorExpr)
if selx == nil {
check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0)
check.rawExpr(x, arg0, nil) // evaluate to avoid spurious "declared but not used" errors
check.use(arg0)
return
}
check.expr(x, selx.X)

View File

@ -16,7 +16,7 @@ func (check *checker) call(x *operand, e *ast.CallExpr) exprKind {
switch x.mode {
case invalid:
check.use(e.Args)
check.use(e.Args...)
x.mode = invalid
x.expr = e
return statement
@ -82,12 +82,12 @@ func (check *checker) call(x *operand, e *ast.CallExpr) exprKind {
}
}
// use type-checks each list element.
// Useful to make sure a list of expressions is evaluated
// use type-checks each argument.
// Useful to make sure expressions are evaluated
// (and variables are "used") in the presence of other errors.
func (check *checker) use(list []ast.Expr) {
func (check *checker) use(arg ...ast.Expr) {
var x operand
for _, e := range list {
for _, e := range arg {
check.rawExpr(&x, e, nil)
}
}

View File

@ -57,9 +57,11 @@ func (check *checker) arityMatch(s, init *ast.ValueSpec) {
// init exprs from s
n := s.Values[l]
check.errorf(n.Pos(), "extra init expr %s", n)
// TODO(gri) avoid declared but not used error here
} else {
// init exprs "inherited"
check.errorf(s.Pos(), "extra init expr at %s", init.Pos())
// TODO(gri) avoid declared but not used error here
}
case l > r && (init != nil || r != 1):
n := s.Names[r]

View File

@ -341,6 +341,7 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
}
} else if len(s.Results) > 0 {
check.error(s.Results[0].Pos(), "no result values expected")
check.use(s.Results...)
}
case *ast.BranchStmt:

View File

@ -5,6 +5,7 @@
package vardecl
// Prerequisites.
import "math"
func f() {}
func g() (x, y int) { return }
var m map[string]int
@ -147,6 +148,26 @@ func (r T) _(a, b, c int) (u, v, w int) {
return
}
// Invalid (unused) expressions must not lead to spurious "declared but not used errors"
func _() {
var a, b, c int
var x, y int
x, y = a /* ERROR assignment count mismatch */ , b, c
_ = x
_ = y
}
func _() {
var x int
return x /* ERROR no result values expected */
return math /* ERROR no result values expected */ .Sin(0)
}
func _() int {
var x, y int
return /* ERROR wrong number of return values */ x, y
}
// Short variable declarations must declare at least one new non-blank variable.
func _() {
_ := /* ERROR no new variables */ 0