// If the assignment is invalid, the result is nil.
func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
if x.mode == invalid || x.typ == Typ[Invalid] {
- check.useLHS(lhs)
+ check.use(lhs)
return nil
}
rhs, commaOk := check.exprList(origRHS, len(lhs) == 2)
if len(lhs) != len(rhs) {
- check.useLHS(lhs...)
+ check.use(lhs...)
// don't report an error if we already reported one
for _, x := range rhs {
if x.mode == invalid {
for i, lhs := range lhs {
ident, _ := lhs.(*ast.Ident)
if ident == nil {
- check.useLHS(lhs)
+ check.use(lhs)
// TODO(rFindley) this is redundant with a parser error. Consider omitting?
check.errorf(lhs, BadDecl, "non-name %s on left side of :=", lhs)
hasErr = true
func (check *Checker) use(arg ...ast.Expr) {
var x operand
for _, e := range arg {
- // The nil check below is necessary since certain AST fields
- // may legally be nil (e.g., the ast.SliceExpr.High field).
- if e != nil {
- check.rawExpr(&x, e, nil, false)
- }
- }
-}
-
-// useLHS is like use, but doesn't "use" top-level identifiers.
-// It should be called instead of use if the arguments are
-// expressions on the lhs of an assignment.
-// The arguments must not be nil.
-func (check *Checker) useLHS(arg ...ast.Expr) {
- var x operand
- for _, e := range arg {
- // If the lhs is an identifier denoting a variable v, this assignment
- // is not a 'use' of v. Remember current value of v.used and restore
- // after evaluating the lhs via check.rawExpr.
- var v *Var
- var v_used bool
- if ident, _ := unparen(e).(*ast.Ident); ident != nil {
- // never type-check the blank name on the lhs
- if ident.Name == "_" {
+ switch n := e.(type) {
+ case nil:
+ // some AST fields may be nil (e.g., the ast.SliceExpr.High field)
+ // TODO(gri) can those fields really make it here?
+ continue
+ case *ast.Ident:
+ // don't report an error evaluating blank
+ if n.Name == "_" {
continue
}
- if _, obj := check.scope.LookupParent(ident.Name, nopos); obj != nil {
- // It's ok to mark non-local variables, but ignore variables
- // from other packages to avoid potential race conditions with
- // dot-imported variables.
- if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
- v = w
- v_used = v.used
- }
- }
}
check.rawExpr(&x, e, nil, false)
- if v != nil {
- v.used = v_used // restore v.used
- }
}
}