From 48026e1f7b6b2cff78f7dda0905ec4ad23126cd9 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Mon, 17 Jul 2023 18:01:44 -0400 Subject: [PATCH] internal/gcimporter: don't panic when exporting a builtin 'Error' method The 'Error' method on the builtin error type is special, because it does not have a package. Fall back to the old behavior in this case, by changing the objectpath encoding from (pkg, objectpath) to (objectpath, pkg), and using "" for objects without a package. Change-Id: I3d7e7ffe4eb3523d3ba758b09372abb7fc80be89 Reviewed-on: https://go-review.googlesource.com/c/tools/+/510416 Reviewed-by: Alan Donovan TryBot-Result: Gopher Robot gopls-CI: kokoro Run-TryBot: Robert Findley --- .../regtest/marker/testdata/references/issue60676.txt | 3 +++ internal/gcimporter/iexport.go | 8 +++++--- internal/gcimporter/iimport.go | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/gopls/internal/regtest/marker/testdata/references/issue60676.txt b/gopls/internal/regtest/marker/testdata/references/issue60676.txt index 25d52983e..9116d7710 100644 --- a/gopls/internal/regtest/marker/testdata/references/issue60676.txt +++ b/gopls/internal/regtest/marker/testdata/references/issue60676.txt @@ -25,12 +25,15 @@ type E struct { type AI interface { M() //@loc(MDef, "M") EI + error } type EI interface { N() //@loc(NDef, "N") } +type Error error + -- b/b.go -- package b diff --git a/internal/gcimporter/iexport.go b/internal/gcimporter/iexport.go index e4a8c4804..3e3fce173 100644 --- a/internal/gcimporter/iexport.go +++ b/internal/gcimporter/iexport.go @@ -907,9 +907,10 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { // type of B, they are encoded as objectPaths and later looked up in the // importer. The same problem applies to interface methods. func (w *exportWriter) objectPath(obj types.Object) { - w.pkg(obj.Pkg()) - if obj.Pkg() == w.p.localpkg { - // If obj is declared in the local package, no need to encode. + if obj.Pkg() == nil || obj.Pkg() == w.p.localpkg { + // obj.Pkg() may be nil for the builtin error.Error. + // In this case, or if obj is declared in the local package, no need to + // encode. w.string("") return } @@ -934,6 +935,7 @@ func (w *exportWriter) objectPath(obj types.Object) { } } w.string(string(objectPath)) + w.pkg(obj.Pkg()) } func (w *exportWriter) signature(sig *types.Signature) { diff --git a/internal/gcimporter/iimport.go b/internal/gcimporter/iimport.go index 2c2d54737..52faa77df 100644 --- a/internal/gcimporter/iimport.go +++ b/internal/gcimporter/iimport.go @@ -978,11 +978,11 @@ func (r *importReader) kind() itag { // imported package. See the doc for exportWriter.objectPath for a full // explanation. func (r *importReader) objectPathObject() types.Object { - pkg := r.pkg() objPath := objectpath.Path(r.string()) if objPath == "" { return nil } + pkg := r.pkg() obj, err := objectpath.Object(pkg, objPath) if err != nil { if r.p.reportf != nil {