internal/lsp/source: fix an infinite loop in Deref function

Return a pointer type if the type refers to itself (for example, type a *a).

Fixes golang/go#45510

Change-Id: Ifaf9c0fe9df8a1cab300479394a7127dfb820a88
GitHub-Last-Rev: 009802341673cfd24c04d6a115a6082029dfa2a2
GitHub-Pull-Request: golang/tools#302
Reviewed-on: https://go-review.googlesource.com/c/tools/+/310050
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Heschi Kreinick <heschi@google.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Shoshin Nikita 2021-04-14 17:37:59 +00:00 committed by Rebecca Stambler
parent 59a2b45a1d
commit d1362d7aca
2 changed files with 42 additions and 0 deletions

View File

@ -374,3 +374,40 @@ type S struct {
}
})
}
func TestCompletion_Issue45510(t *testing.T) {
const files = `
-- go.mod --
module mod.com
go 1.12
-- main.go --
package main
func _() {
type a *a
var aaaa1, aaaa2 a
var _ a = aaaa
type b a
var bbbb1, bbbb2 b
var _ b = bbbb
}
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
completions := env.Completion("main.go", env.RegexpSearch("main.go", `var _ a = aaaa()`))
diff := compareCompletionResults([]string{"aaaa1", "aaaa2"}, completions.Items)
if diff != "" {
t.Fatal(diff)
}
completions = env.Completion("main.go", env.RegexpSearch("main.go", `var _ b = bbbb()`))
diff = compareCompletionResults([]string{"bbbb1", "bbbb2"}, completions.Items)
if diff != "" {
t.Fatal(diff)
}
})
}

View File

@ -221,12 +221,17 @@ func FormatNode(fset *token.FileSet, n ast.Node) string {
// Deref returns a pointer's element type, traversing as many levels as needed.
// Otherwise it returns typ.
//
// It can return a pointer type if the type refers to itself (see golang/go#45510).
func Deref(typ types.Type) types.Type {
for {
p, ok := typ.Underlying().(*types.Pointer)
if !ok {
return typ
}
if typ == p.Elem() {
return typ
}
typ = p.Elem()
}
}