internal/lsp: fix panic in find references on Error
Our find references don't support (error).Error, but in this case, find
references actually panicked.
Fixes golang/go#48400
Change-Id: I68d6ea93528dc5425f59f0e952f03081c5a7847a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/350132
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regtest/misc/references_test.go
index f3a23e4..7682516 100644
--- a/gopls/internal/regtest/misc/references_test.go
+++ b/gopls/internal/regtest/misc/references_test.go
@@ -42,3 +42,42 @@
}
})
}
+
+// This reproduces and tests golang/go#48400.
+func TestReferencesPanicOnError(t *testing.T) {
+ const files = `
+-- go.mod --
+module mod.com
+
+go 1.12
+-- main.go --
+package main
+
+type t interface {
+ error
+}
+
+type s struct{}
+
+func (*s) Error() string {
+ return ""
+}
+
+func _() {
+ var s s
+ _ = s.Error()
+}
+`
+ Run(t, files, func(t *testing.T, env *Env) {
+ env.OpenFile("main.go")
+ file, pos := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `Error`))
+ refs, err := env.Editor.References(env.Ctx, file, pos)
+ if err == nil {
+ t.Fatalf("expected error for references, instead got %v", refs)
+ }
+ wantErr := "no position for func (error).Error() string"
+ if err.Error() != wantErr {
+ t.Fatalf("expected error with message %s, instead got %s", wantErr, err.Error())
+ }
+ })
+}
diff --git a/internal/lsp/source/references.go b/internal/lsp/source/references.go
index 1cd9a40..993b9f8 100644
--- a/internal/lsp/source/references.go
+++ b/internal/lsp/source/references.go
@@ -6,6 +6,7 @@
import (
"context"
+ "fmt"
"go/ast"
"go/token"
"go/types"
@@ -68,7 +69,11 @@
seen = make(map[token.Pos]bool)
)
- filename := snapshot.FileSet().Position(qos[0].obj.Pos()).Filename
+ pos := qos[0].obj.Pos()
+ if pos == token.NoPos {
+ return nil, fmt.Errorf("no position for %s", qos[0].obj)
+ }
+ filename := snapshot.FileSet().Position(pos).Filename
pgf, err := qos[0].pkg.File(span.URIFromPath(filename))
if err != nil {
return nil, err