]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: better error when assigning to struct field in map
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Sat, 2 Apr 2016 15:04:45 +0000 (12:04 -0300)
committerDavid Chase <drchase@google.com>
Mon, 4 Apr 2016 15:10:48 +0000 (15:10 +0000)
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>

src/go/types/assignments.go
src/go/types/testdata/stmt0.src

index 10ab17b9cf9ab4753db70556ff9e5747cf2748eb..c7564bcf85d355772a9ec514eb214cf86a70fe66 100644 (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
        }
index fec16e1dd7ab0eceb86e2e137f0cf46acf7260b8..e0d714dfb6f11078a6f97258d5c0823960fdf550 100644 (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
 }