From df07577eb15b63c13c0ff5c699cc34626b6dcf3f Mon Sep 17 00:00:00 2001 From: Muir Manders Date: Fri, 28 May 2021 17:39:50 -0700 Subject: [PATCH] lsp/completion: fix variadic param candidate ordering edge case In cases like: var foo func(...interface{}) var one int var two func() (int, int) foo(<>) At <> we were preferring "two()" over "one" because we were really excited that the multi return value function was usable. "one" was not preferred because the expected value is interface{} (we default to saying candidates _don't_ match interface{} to give non-type based aspects of candidate inference a chance to shine). Fix by applying the corresponding interface{} logic to the assignees checking: ignore the case of completing into func(...interface{}) since all multi return value functions would match. Fixes golang/go#46378. Change-Id: I355daa75e067e8b14508ca50b8d3b6b727df5fec Reviewed-on: https://go-review.googlesource.com/c/tools/+/323509 Run-TryBot: Muir Manders gopls-CI: kokoro TryBot-Result: Go Bot Reviewed-by: Rebecca Stambler Trust: Peter Weinberger --- internal/lsp/source/completion/completion.go | 6 ++++++ internal/lsp/testdata/multireturn/multi_return.go.in | 9 +++++++++ internal/lsp/testdata/summary.txt.golden | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go index 2c9a8262cd..6d4bef93e0 100644 --- a/internal/lsp/source/completion/completion.go +++ b/internal/lsp/source/completion/completion.go @@ -2702,6 +2702,12 @@ func (ci *candidateInference) assigneesMatch(cand *candidate, sig *types.Signatu return false } + // Don't prefer completing into func(...interface{}) calls since all + // functions wouuld match. + if ci.variadicAssignees && len(ci.assignees) == 1 && isEmptyInterface(deslice(ci.assignees[0])) { + return false + } + var numberOfResultsCouldMatch bool if ci.variadicAssignees { numberOfResultsCouldMatch = sig.Results().Len() >= len(ci.assignees)-1 diff --git a/internal/lsp/testdata/multireturn/multi_return.go.in b/internal/lsp/testdata/multireturn/multi_return.go.in index 712070b2e6..c302f3815f 100644 --- a/internal/lsp/testdata/multireturn/multi_return.go.in +++ b/internal/lsp/testdata/multireturn/multi_return.go.in @@ -37,3 +37,12 @@ func _() { var variadic func(int, ...int) variadic() //@rank(")", multiF1, multiF0),rank(")", multiF2, multiF0),rank(")", multiF3, multiF0) } + +func _() { + var baz func(...interface{}) + + var otterNap func() (int, int) //@item(multiTwo, "otterNap", "func() (int, int)", "var") + var one int //@item(multiOne, "one", "int", "var") + + baz(on) //@rank(")", multiOne, multiTwo) +} diff --git a/internal/lsp/testdata/summary.txt.golden b/internal/lsp/testdata/summary.txt.golden index 91dd9ada1a..d783d792b6 100644 --- a/internal/lsp/testdata/summary.txt.golden +++ b/internal/lsp/testdata/summary.txt.golden @@ -6,7 +6,7 @@ CompletionSnippetCount = 95 UnimportedCompletionsCount = 5 DeepCompletionsCount = 5 FuzzyCompletionsCount = 8 -RankedCompletionsCount = 165 +RankedCompletionsCount = 166 CaseSensitiveCompletionsCount = 4 DiagnosticsCount = 37 FoldingRangesCount = 2