From 22ba3f367cb7983f78ca68a0be06b92c5d316797 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Fri, 11 Nov 2016 16:06:02 -0500 Subject: [PATCH] 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 --- go/gcimporter15/bimport.go | 14 ++++++++++++++ go/gcimporter15/gcimporter.go | 13 +++++++++++++ 2 files changed, 27 insertions(+) diff --git a/go/gcimporter15/bimport.go b/go/gcimporter15/bimport.go index e0ca8c9eda..ce4b6872bb 100644 --- a/go/gcimporter15/bimport.go +++ b/go/gcimporter15/bimport.go @@ -616,6 +616,20 @@ func (p *importer) fieldName(parent *types.Package) (*types.Package, string) { } if p.version == 0 && name == "_" { // 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 } if name != "" && !exported(name) { diff --git a/go/gcimporter15/gcimporter.go b/go/gcimporter15/gcimporter.go index 48a4ef29e1..6fbc9d7617 100644 --- a/go/gcimporter15/gcimporter.go +++ b/go/gcimporter15/gcimporter.go @@ -500,6 +500,19 @@ func deref(typ types.Type) types.Type { // func (p *parser) parseField(parent *types.Package) (*types.Var, string) { 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) anonymous := false if name == "" {