1
0
mirror of https://github.com/golang/go synced 2024-11-18 18:44:42 -07:00

go/gcimporter15: pretend blank fields have same owner

The export data formats (text and binary) emitted by gc in Go 1.7 did
not record the package that "owns" each blank field, even though blank
is an unexported identifier.  Before, gcimporter would assume the
package of the export data file owns blank fields within it, even
blank fields reexported from another package.  As a result, identical
types would become nonidentical during reexporting.

For bug compatibility with gc, gcimporter now treats blank fields as
if they all belong to the same dummy package, avoiding spurious "can't
assign A to B" errors in tools based on go/types.

Change-Id: I0dbf71491a0ec0f376e9dc8a91efe0376c855a28
Reviewed-on: https://go-review.googlesource.com/33146
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Alan Donovan 2016-11-11 16:06:02 -05:00
parent a69656e0e2
commit 22ba3f367c
2 changed files with 27 additions and 0 deletions

View File

@ -616,6 +616,20 @@ func (p *importer) fieldName(parent *types.Package) (*types.Package, string) {
} }
if p.version == 0 && name == "_" { if p.version == 0 && name == "_" {
// version 0 didn't export a package for _ fields // version 0 didn't export a package for _ fields
// see issue #15514
// For bug-compatibility with gc, pretend all imported
// blank fields belong to the same dummy package.
// This avoids spurious "cannot assign A to B" errors
// from go/types caused by types changing as they are
// re-exported.
const blankpkg = "<_>"
pkg := p.imports[blankpkg]
if pkg == nil {
pkg = types.NewPackage(blankpkg, blankpkg)
p.imports[blankpkg] = pkg
}
return pkg, name return pkg, name
} }
if name != "" && !exported(name) { if name != "" && !exported(name) {

View File

@ -500,6 +500,19 @@ func deref(typ types.Type) types.Type {
// //
func (p *parser) parseField(parent *types.Package) (*types.Var, string) { func (p *parser) parseField(parent *types.Package) (*types.Var, string) {
pkg, name := p.parseName(parent, true) pkg, name := p.parseName(parent, true)
if name == "_" {
// Blank fields should be package-qualified because they
// are unexported identifiers, but gc does not qualify them.
// Assuming that the ident belongs to the current package
// causes types to change during re-exporting, leading
// to spurious "can't assign A to B" errors from go/types.
// As a workaround, pretend all blank fields belong
// to the same unique dummy package.
const blankpkg = "<_>"
pkg = p.getPkg(blankpkg, blankpkg)
}
typ := p.parseType(parent) typ := p.parseType(parent)
anonymous := false anonymous := false
if name == "" { if name == "" {