go/types: better error when assigning to struct field in map

Identify this assignment case and instead of the more general error

    prog.go:6: cannot assign to students["sally"].age (value of type int)

produce

    prog.go:6: cannot directly assign to struct field students["sally"].age in map

that explains why the assignment is not possible. Used ExprString
instead of String of operand since the type of the field is not relevant
to the error.

Updates #13779.

Change-Id: I581251145ae6336ddd181b9ddd77f657c51b5aff
Reviewed-on: https://go-review.googlesource.com/21463
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Caio Marcelo de Oliveira Filho 2016-04-02 12:04:45 -03:00 committed by David Chase
parent f229e46783
commit 74c0fea9e8
2 changed files with 9 additions and 1 deletions

View file

@ -179,6 +179,14 @@ func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
case variable, mapindex:
// ok
default:
if sel, ok := z.expr.(*ast.SelectorExpr); ok {
var op operand
check.expr(&op, sel.X)
if op.mode == mapindex {
check.errorf(z.pos(), "cannot directly assign to struct field %s in map", ExprString(z.expr))
return nil
}
}
check.errorf(z.pos(), "cannot assign to %s", &z)
return nil
}

View file

@ -137,7 +137,7 @@ func issue6487() {
type M map[string]S
var m M
m /* ERROR "cannot assign" */ ["foo"].x = 0
m /* ERROR "cannot directly assign to struct field" */ ["foo"].x = 0
_ = &( /* ERROR "cannot take address" */ m["foo"].x)
_ = &m /* ERROR "cannot take address" */ ["foo"].x
}