Skip to content

Commit 7bc99ff

Browse files
odeke-emgriesemer
authored andcommitted
cmd/compile: make case insensitive suggestions aware of package
Ensure that compiler error suggestions after case insensitive field lookups don't mistakenly reported unexported fields if those fields aren't in the local package being processed. Fixes #25727 Change-Id: Icae84388c2a82c8cb539f3d43ad348f50a644caa Reviewed-on: https://go-review.googlesource.com/117755 Run-TryBot: Emmanuel Odeke <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent b8dc931 commit 7bc99ff

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/cmd/compile/internal/gc/typecheck.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@ func typecheck1(n *Node, top int) *Node {
919919
yyerror("%v undefined (cannot refer to unexported field or method %v)", n, n.Sym)
920920

921921
default:
922-
if mt := lookdot(n, t, 2); mt != nil { // Case-insensitive lookup.
922+
if mt := lookdot(n, t, 2); mt != nil && visible(mt.Sym) { // Case-insensitive lookup.
923923
yyerror("%v undefined (type %v has no field or method %v, but does have %v)", n, n.Left.Type, n.Sym, mt.Sym)
924924
} else {
925925
yyerror("%v undefined (type %v has no field or method %v)", n, n.Left.Type, n.Sym)
@@ -3132,7 +3132,11 @@ func typecheckcomplit(n *Node) *Node {
31323132
f := lookdot1(nil, l.Sym, t, t.Fields(), 0)
31333133
if f == nil {
31343134
if ci := lookdot1(nil, l.Sym, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup.
3135-
yyerror("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym)
3135+
if visible(ci.Sym) {
3136+
yyerror("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym)
3137+
} else {
3138+
yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
3139+
}
31363140
continue
31373141
}
31383142
p, _ := dotpath(l.Sym, t, nil, true)
@@ -3179,6 +3183,11 @@ func typecheckcomplit(n *Node) *Node {
31793183
return n
31803184
}
31813185

3186+
// visible reports whether sym is exported or locally defined.
3187+
func visible(sym *types.Sym) bool {
3188+
return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == localpkg)
3189+
}
3190+
31823191
// lvalue etc
31833192
func islvalue(n *Node) bool {
31843193
switch n.Op {

test/fixedbugs/issue25727.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// errorcheck
2+
3+
// Copyright 2018 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package main
8+
9+
import "net/http"
10+
11+
var s = http.Server{}
12+
var _ = s.doneChan // ERROR "s.doneChan undefined .cannot refer to unexported field or method doneChan.$"
13+
var _ = s.DoneChan // ERROR "s.DoneChan undefined .type http.Server has no field or method DoneChan.$"
14+
var _ = http.Server{tlsConfig: nil} // ERROR "unknown field 'tlsConfig' in struct literal.+ .but does have TLSConfig.$"
15+
var _ = http.Server{DoneChan: nil} // ERROR "unknown field 'DoneChan' in struct literal of type http.Server$"
16+
17+
type foo struct {
18+
bar int
19+
}
20+
21+
var _ = &foo{bAr: 10} // ERROR "unknown field 'bAr' in struct literal.+ .but does have bar.$"

0 commit comments

Comments
 (0)