mirror of
https://github.com/golang/go
synced 2024-10-06 08:00:07 +00:00
go/types: fewer spurious "declared but not used" follow-on errors
Mark variables as used even when they appear within an expression context which we can't type-check; e.g., because the expression is erroneous, or comes from an import "C" declaration. Fixes #20358. Change-Id: Ib28cc78d3867c597c7a1ace54de09ada02f5b33a Reviewed-on: https://go-review.googlesource.com/43500 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
27da3ba5af
commit
5088b64b07
|
@ -93,7 +93,9 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
|
|||
func (check *Checker) use(arg ...ast.Expr) {
|
||||
var x operand
|
||||
for _, e := range arg {
|
||||
check.rawExpr(&x, e, nil)
|
||||
if e != nil { // be safe
|
||||
check.rawExpr(&x, e, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1161,6 +1161,17 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
|||
}
|
||||
|
||||
default:
|
||||
// when "using" all elements unpack KeyValueExpr
|
||||
// explicitly because check.use doesn't accept them
|
||||
for _, e := range e.Elts {
|
||||
if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
|
||||
// Ideally, we should also "use" kv.Key but we can't know
|
||||
// if it's an externally defined struct key or not. Going
|
||||
// forward anyway can lead to other errors. Give up instead.
|
||||
e = kv.Value
|
||||
}
|
||||
check.use(e)
|
||||
}
|
||||
// if utyp is invalid, an error was reported before
|
||||
if utyp != Typ[Invalid] {
|
||||
check.errorf(e.Pos(), "invalid composite literal type %s", typ)
|
||||
|
@ -1182,6 +1193,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
|||
case *ast.IndexExpr:
|
||||
check.expr(x, e.X)
|
||||
if x.mode == invalid {
|
||||
check.use(e.Index)
|
||||
goto Error
|
||||
}
|
||||
|
||||
|
@ -1251,6 +1263,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
|||
case *ast.SliceExpr:
|
||||
check.expr(x, e.X)
|
||||
if x.mode == invalid {
|
||||
check.use(e.Low, e.High, e.Max)
|
||||
goto Error
|
||||
}
|
||||
|
||||
|
|
21
src/go/types/testdata/issues.src
vendored
21
src/go/types/testdata/issues.src
vendored
|
@ -186,3 +186,24 @@ func issue15755() {
|
|||
_ = u
|
||||
_ = v
|
||||
}
|
||||
|
||||
// Test that we don't get "declared but not used"
|
||||
// errors in the context of invalid/C objects.
|
||||
func issue20358() {
|
||||
var F C /* ERROR "undeclared" */ .F
|
||||
var A C /* ERROR "undeclared" */ .A
|
||||
var S C /* ERROR "undeclared" */ .S
|
||||
type T C /* ERROR "undeclared" */ .T
|
||||
type P C /* ERROR "undeclared" */ .P
|
||||
|
||||
// these variables must be "used" even though
|
||||
// the LHS expressions/types below in which
|
||||
// context they are used are unknown/invalid
|
||||
var f, a, s1, s2, s3, t, p int
|
||||
|
||||
_ = F(f)
|
||||
_ = A[a]
|
||||
_ = S[s1:s2:s3]
|
||||
_ = T{t}
|
||||
_ = P{f: p}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue