From 7cbee1244437bafa1e52ca761d7c32d7587a9fdd Mon Sep 17 00:00:00 2001 From: Emmanuel T Odeke Date: Wed, 16 Oct 2019 23:13:25 -0700 Subject: cmd/compile: improve error when setting unexported fields Improve the error user experience when users try to set/refer to unexported fields and methods of struct literals, by directly saying "cannot refer to unexported field or method" Fixes #31053 Change-Id: I6fd3caf64b7ca9f9d8ea60b7756875e340792d59 Reviewed-on: https://go-review.googlesource.com/c/go/+/201657 Run-TryBot: Emmanuel Odeke Reviewed-by: Matthew Dempsky TryBot-Result: Gobot Gobot --- src/cmd/compile/internal/gc/typecheck.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/cmd') diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index 8132aee863..dec4b96fc4 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -2967,6 +2967,8 @@ func typecheckcomplit(n *Node) (res *Node) { if ci := lookdot1(nil, l.Sym, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup. if visible(ci.Sym) { yyerror("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym) + } else if nonexported(l.Sym) && l.Sym.Name == ci.Sym.Name { // Ensure exactness before the suggestion. + yyerror("cannot refer to unexported field '%v' in struct literal of type %v", l.Sym, t) } else { yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t) } @@ -3070,6 +3072,11 @@ func visible(sym *types.Sym) bool { return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == localpkg) } +// nonexported reports whether sym is an unexported field. +func nonexported(sym *types.Sym) bool { + return sym != nil && !types.IsExported(sym.Name) +} + // lvalue etc func islvalue(n *Node) bool { switch n.Op { -- cgit v1.3-5-g45d5