From 118c362a56589bbbb0a0950d2d5e8850d5366609 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Fri, 3 Nov 2023 15:45:48 -0400 Subject: [PATCH] gopls/internal/lsp/source: fix signatureHelp with pointer receivers I just ran into this today. Alas, it took us too long to fix this. Fixes golang/go#61189 Change-Id: Iac28a6ba30d099cb2bb6f9d761ee658e190aa07c Reviewed-on: https://go-review.googlesource.com/c/tools/+/539677 Reviewed-by: Alan Donovan LUCI-TryBot-Result: Go LUCI --- gopls/internal/lsp/source/types_format.go | 6 +++++- .../marker/testdata/signature/generic.txt | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 gopls/internal/regtest/marker/testdata/signature/generic.txt diff --git a/gopls/internal/lsp/source/types_format.go b/gopls/internal/lsp/source/types_format.go index 1fcad26bb11..8ea81f5db27 100644 --- a/gopls/internal/lsp/source/types_format.go +++ b/gopls/internal/lsp/source/types_format.go @@ -312,7 +312,11 @@ func FormatVarType(ctx context.Context, snapshot Snapshot, srcpkg Package, obj * return types.TypeString(obj.Type(), qf), nil // in generic function } if decl.Recv != nil && len(decl.Recv.List) > 0 { - if x, _, _, _ := typeparams.UnpackIndexExpr(decl.Recv.List[0].Type); x != nil { + rtype := decl.Recv.List[0].Type + if e, ok := rtype.(*ast.StarExpr); ok { + rtype = e.X + } + if x, _, _, _ := typeparams.UnpackIndexExpr(rtype); x != nil { return types.TypeString(obj.Type(), qf), nil // in method of generic type } } diff --git a/gopls/internal/regtest/marker/testdata/signature/generic.txt b/gopls/internal/regtest/marker/testdata/signature/generic.txt new file mode 100644 index 00000000000..e99abbf1dad --- /dev/null +++ b/gopls/internal/regtest/marker/testdata/signature/generic.txt @@ -0,0 +1,21 @@ +This test checks signature help on generic signatures. + +-- g.go -- +package g + +type M[K comparable, V any] map[K]V + +// golang/go#61189: signatureHelp must handle pointer receivers. +func (m *M[K, V]) Get(k K) V { + return (*m)[k] +} + +func Get[K comparable, V any](m M[K, V], k K) V { + return m[k] +} + +func _() { + var m M[int, string] + _ = m.Get(0) //@signature("(", "Get(k int) string", 0) + _ = Get(m, 0) //@signature("0", "Get(m M[int, string], k int) string", 1) +}