Skip to content

Commit 0edd1ab

Browse files
committed
gopls/internal/cache/methodsets: refine crash for missing object path
We can't reproduce the crash observed in golang/go#70418, where a method on a package level type name has no object path. In any case, downgrade this crash to a bug report, and refine the report to clarify some conditions potentially related to the crash. For golang/go#70418 Change-Id: If6ab38e2189accf881e84da568525e2228c757fb Reviewed-on: https://go-review.googlesource.com/c/tools/+/631778 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent 07a58bc commit 0edd1ab

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

gopls/internal/cache/methodsets/methodsets.go

+33-7
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ import (
5252
"strings"
5353

5454
"golang.org/x/tools/go/types/objectpath"
55+
"golang.org/x/tools/gopls/internal/util/bug"
5556
"golang.org/x/tools/gopls/internal/util/frob"
5657
"golang.org/x/tools/gopls/internal/util/safetoken"
58+
"golang.org/x/tools/internal/typesinternal"
5759
)
5860

5961
// An Index records the non-empty method sets of all package-level
@@ -223,16 +225,40 @@ func (b *indexBuilder) build(fset *token.FileSet, pkg *types.Package) *Index {
223225
return
224226
}
225227

226-
m.Posn = objectPos(method)
227-
m.PkgPath = b.string(method.Pkg().Path())
228-
229228
// Instantiations of generic methods don't have an
230229
// object path, so we use the generic.
231-
if p, err := objectpathFor(method.Origin()); err != nil {
232-
panic(err) // can't happen for a method of a package-level type
233-
} else {
234-
m.ObjectPath = b.string(string(p))
230+
p, err := objectpathFor(method.Origin())
231+
if err != nil {
232+
// This should never happen for a method of a package-level type.
233+
// ...but it does (golang/go#70418).
234+
// Refine the crash into various bug reports.
235+
report := func() {
236+
bug.Reportf("missing object path for %s", method.FullName())
237+
}
238+
sig := method.Signature()
239+
if sig.Recv() == nil {
240+
report()
241+
return
242+
}
243+
_, named := typesinternal.ReceiverNamed(sig.Recv())
244+
switch {
245+
case named == nil:
246+
report()
247+
case sig.TypeParams().Len() > 0:
248+
report()
249+
case method.Origin() != method:
250+
report() // instantiated?
251+
case sig.RecvTypeParams().Len() > 0:
252+
report() // generic?
253+
default:
254+
report()
255+
}
256+
return
235257
}
258+
259+
m.Posn = objectPos(method)
260+
m.PkgPath = b.string(method.Pkg().Path())
261+
m.ObjectPath = b.string(string(p))
236262
}
237263

238264
// We ignore aliases, though in principle they could define a

0 commit comments

Comments
 (0)