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>
diff --git a/gopls/internal/regtest/completion/completion_test.go b/gopls/internal/regtest/completion/completion_test.go
index 6e89c4f..82f0757 100644
--- a/gopls/internal/regtest/completion/completion_test.go
+++ b/gopls/internal/regtest/completion/completion_test.go
@@ -374,3 +374,40 @@
 		}
 	})
 }
+
+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)
+		}
+	})
+}
diff --git a/internal/lsp/source/util.go b/internal/lsp/source/util.go
index 690a781..d242c34 100644
--- a/internal/lsp/source/util.go
+++ b/internal/lsp/source/util.go
@@ -221,12 +221,17 @@
 
 // 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()
 	}
 }