Skip to content

Commit d1362d7

Browse files
ShoshinNikitastamblerre
authored andcommitted
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: 0098023 GitHub-Pull-Request: #302 Reviewed-on: https://go-review.googlesource.com/c/tools/+/310050 Trust: Rebecca Stambler <[email protected]> Trust: Heschi Kreinick <[email protected]> Run-TryBot: Rebecca Stambler <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]>
1 parent 59a2b45 commit d1362d7

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

gopls/internal/regtest/completion/completion_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,3 +374,40 @@ type S struct {
374374
}
375375
})
376376
}
377+
378+
func TestCompletion_Issue45510(t *testing.T) {
379+
const files = `
380+
-- go.mod --
381+
module mod.com
382+
383+
go 1.12
384+
-- main.go --
385+
package main
386+
387+
func _() {
388+
type a *a
389+
var aaaa1, aaaa2 a
390+
var _ a = aaaa
391+
392+
type b a
393+
var bbbb1, bbbb2 b
394+
var _ b = bbbb
395+
}
396+
`
397+
398+
Run(t, files, func(t *testing.T, env *Env) {
399+
env.OpenFile("main.go")
400+
401+
completions := env.Completion("main.go", env.RegexpSearch("main.go", `var _ a = aaaa()`))
402+
diff := compareCompletionResults([]string{"aaaa1", "aaaa2"}, completions.Items)
403+
if diff != "" {
404+
t.Fatal(diff)
405+
}
406+
407+
completions = env.Completion("main.go", env.RegexpSearch("main.go", `var _ b = bbbb()`))
408+
diff = compareCompletionResults([]string{"bbbb1", "bbbb2"}, completions.Items)
409+
if diff != "" {
410+
t.Fatal(diff)
411+
}
412+
})
413+
}

internal/lsp/source/util.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,17 @@ func FormatNode(fset *token.FileSet, n ast.Node) string {
221221

222222
// Deref returns a pointer's element type, traversing as many levels as needed.
223223
// Otherwise it returns typ.
224+
//
225+
// It can return a pointer type if the type refers to itself (see golang/go#45510).
224226
func Deref(typ types.Type) types.Type {
225227
for {
226228
p, ok := typ.Underlying().(*types.Pointer)
227229
if !ok {
228230
return typ
229231
}
232+
if typ == p.Elem() {
233+
return typ
234+
}
230235
typ = p.Elem()
231236
}
232237
}

0 commit comments

Comments
 (0)