From 74c0fea9e8a37ae08d4c08b71d27be94feb3332a Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Sat, 2 Apr 2016 12:04:45 -0300 Subject: [PATCH] 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 Run-TryBot: David Chase TryBot-Result: Gobot Gobot --- src/go/types/assignments.go | 8 ++++++++ src/go/types/testdata/stmt0.src | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go index 10ab17b9cf..c7564bcf85 100644 --- a/src/go/types/assignments.go +++ b/src/go/types/assignments.go @@ -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 } diff --git a/src/go/types/testdata/stmt0.src b/src/go/types/testdata/stmt0.src index fec16e1dd7..e0d714dfb6 100644 --- a/src/go/types/testdata/stmt0.src +++ b/src/go/types/testdata/stmt0.src @@ -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 } -- 2.48.1