1
0
mirror of https://github.com/golang/go synced 2024-09-24 03:10:16 -06:00

cmd/compile: export package for _ (blank) struct fields

Blank struct fields are regular unexported fields. Two
blank fields are different if they are from different
packages. In order to correctly differentiate them, the
compiler needs the package information. Add it to the
export data.

Fixes #15514.

Change-Id: I421aaca22b542fcd0d66b2d2db777249cad78df6
Reviewed-on: https://go-review.googlesource.com/27639
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Robert Griesemer 2016-08-23 16:02:19 -07:00
parent a8eb6d51bb
commit 6394eb378e
7 changed files with 37 additions and 18 deletions

View File

@ -858,11 +858,9 @@ func (p *exporter) method(m *Field) {
p.paramList(m.Type.Results(), false)
}
// fieldName is like qualifiedName but it doesn't record the package
// for blank (_) or exported names.
// fieldName is like qualifiedName but it doesn't record the package for exported names.
func (p *exporter) fieldName(t *Field) {
name := t.Sym.Name
if t.Embedded != 0 {
name = "" // anonymous field
if bname := basetypeName(t.Type); bname != "" && !exportname(bname) {
@ -871,8 +869,7 @@ func (p *exporter) fieldName(t *Field) {
}
}
p.string(name)
if name != "_" && name != "" && !exportname(name) {
if name != "" && !exportname(name) {
p.pkg(t.Sym.Pkg)
}
}

View File

@ -590,12 +590,7 @@ func (p *importer) method() *Node {
func (p *importer) fieldName() *Sym {
name := p.string()
pkg := localpkg
if name == "_" {
// During imports, unqualified non-exported identifiers are from builtinpkg
// (see parser.go:sym). The binary exporter only exports blank as a non-exported
// identifier without qualification.
pkg = builtinpkg
} else if name != "" && !exportname(name) {
if name != "" && !exportname(name) {
if name == "?" {
name = ""
}

View File

@ -492,19 +492,15 @@ func (p *importer) method(parent *types.Package) *types.Func {
}
func (p *importer) fieldName(parent *types.Package) (*types.Package, string) {
name := p.string()
pkg := parent
if pkg == nil {
// use the imported package instead
pkg = p.pkgList[0]
}
name := p.string()
if name == "" {
return pkg, "" // anonymous
}
if name == "?" || name != "_" && !exported(name) {
// explicitly qualified field
if name != "" && !exported(name) {
if name == "?" {
name = "" // anonymous
name = ""
}
pkg = p.pkg()
}

View File

@ -0,0 +1,7 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package a
type A struct{ _ int32 }

View File

@ -0,0 +1,7 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package b
func B() (_ struct{ _ int32 }) { return }

View File

@ -0,0 +1,10 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package c
import "./a"
import "./b"
var _ a.A = b.B() // ERROR "cannot use b\.B"

View File

@ -0,0 +1,7 @@
// errorcheckdir
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ignored