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 <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
This commit is contained in:
Rob Findley 2023-07-17 18:01:44 -04:00 коммит произвёл Robert Findley
Родитель 5fed7a883c
Коммит 48026e1f7b
3 изменённых файлов: 9 добавлений и 4 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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 {