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:
parent
a4491f08bf
commit
a781b00b0d
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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:
|
||||
|
21
go/types/testdata/vardecl.src
vendored
21
go/types/testdata/vardecl.src
vendored
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user