diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go index 6f33ca1597..fa16357066 100644 --- a/src/cmd/compile/internal/typecheck/iexport.go +++ b/src/cmd/compile/internal/typecheck/iexport.go @@ -617,6 +617,11 @@ func (w *exportWriter) selector(s *types.Sym) { base.Fatalf("missing currPkg") } + // If the selector being written is unexported, it comes with a package qualifier. + // If the selector being written is exported, it is not package-qualified. + // See the spec: https://golang.org/ref/spec#Uniqueness_of_identifiers + // As an optimization, we don't actually write the package every time - instead we + // call setPkg before a group of selectors (all of which must have the same package qualifier). pkg := w.currPkg if types.IsExported(s.Name) { pkg = types.LocalPkg @@ -628,6 +633,26 @@ func (w *exportWriter) selector(s *types.Sym) { w.string(s.Name) } +// Export a selector, but one whose package may not match +// the package being compiled. This is a separate function +// because the standard selector() serialization format is fixed +// by the go/types reader. This one can only be used during +// inline/generic body exporting. +func (w *exportWriter) exoticSelector(s *types.Sym) { + pkg := w.currPkg + if types.IsExported(s.Name) { + pkg = types.LocalPkg + } + + w.string(s.Name) + if s.Pkg == pkg { + w.uint64(0) + } else { + w.uint64(1) + w.pkg(s.Pkg) + } +} + func (w *exportWriter) typ(t *types.Type) { w.data.uint64(w.p.typOff(t)) } @@ -1299,21 +1324,6 @@ func simplifyForExport(n ir.Node) ir.Node { case ir.OPAREN: n := n.(*ir.ParenExpr) return simplifyForExport(n.X) - case ir.ODEREF: - n := n.(*ir.StarExpr) - if n.Implicit() { - return simplifyForExport(n.X) - } - case ir.OADDR: - n := n.(*ir.AddrExpr) - if n.Implicit() { - return simplifyForExport(n.X) - } - case ir.ODOT, ir.ODOTPTR: - n := n.(*ir.SelectorExpr) - if n.Implicit() { - return simplifyForExport(n.X) - } } return n } @@ -1437,7 +1447,7 @@ func (w *exportWriter) expr(n ir.Node) { w.op(ir.OXDOT) w.pos(n.Pos()) w.expr(n.X) - w.selector(n.Sel) + w.exoticSelector(n.Sel) case ir.ODOTTYPE, ir.ODOTTYPE2: n := n.(*ir.TypeAssertExpr) diff --git a/src/cmd/compile/internal/typecheck/iimport.go b/src/cmd/compile/internal/typecheck/iimport.go index 5c57373b66..91bb215a29 100644 --- a/src/cmd/compile/internal/typecheck/iimport.go +++ b/src/cmd/compile/internal/typecheck/iimport.go @@ -466,6 +466,21 @@ func (r *importReader) ident(selector bool) *types.Sym { func (r *importReader) localIdent() *types.Sym { return r.ident(false) } func (r *importReader) selector() *types.Sym { return r.ident(true) } +func (r *importReader) exoticSelector() *types.Sym { + name := r.string() + if name == "" { + return nil + } + pkg := r.currPkg + if types.IsExported(name) { + pkg = types.LocalPkg + } + if r.uint64() != 0 { + pkg = r.pkg() + } + return pkg.Lookup(name) +} + func (r *importReader) qualifiedIdent() *ir.Ident { name := r.string() pkg := r.pkg() @@ -753,7 +768,7 @@ func (r *importReader) doInline(fn *ir.Func) { base.Fatalf("%v already has inline body", fn) } - //fmt.Printf("Importing %v\n", n) + //fmt.Printf("Importing %s\n", fn.Nname.Sym().Name) r.funcBody(fn) importlist = append(importlist, fn) @@ -1038,7 +1053,7 @@ func (r *importReader) node() ir.Node { case ir.OXDOT: // see parser.new_dotname - return ir.NewSelectorExpr(r.pos(), ir.OXDOT, r.expr(), r.selector()) + return ir.NewSelectorExpr(r.pos(), ir.OXDOT, r.expr(), r.exoticSelector()) // case ODOTTYPE, ODOTTYPE2: // unreachable - mapped to case ODOTTYPE below by exporter