internal/lsp/completion: fix invalid struct literal field snippet

In cases like:

    type foo struct { a int; b float64 }
    foo{b<>}

We were completing to "foo{int(b: <float64>)}" (the problem being the
nonsensical int() conversion).

The expected type at "<>" is int to allow completions to match "a".
When we pass the *types.Var representing "b" through the candidate
matching machinery, we say "Oh, a float64! I can convert that to my
expected type of int!".

Fix by bailing out of candidate matching early if the candidate is a
composite literal struct field name. Field names aren't really objects
you can do anything to.

Fixes golang/go#43789.

Change-Id: Ie4dab166973dfcdcb519f864532ead1f792d25a3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/289130
Run-TryBot: Muir Manders <muir@mnd.rs>
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>
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
Muir Manders 2021-02-02 22:29:19 -08:00 committed by Rebecca Stambler
parent c3a8a1d828
commit 8938cee73c
3 changed files with 14 additions and 1 deletions

View File

@ -2444,6 +2444,11 @@ func (c *completer) matchingCandidate(cand *candidate) bool {
return false
}
// Bail out early if we are completing a field name in a composite literal.
if v, ok := cand.obj.(*types.Var); ok && v.IsField() && c.wantStructFieldCompletions() {
return true
}
if isTypeName(cand.obj) {
return c.matchingTypeName(cand)
} else if c.wantTypeName() {

View File

@ -51,3 +51,11 @@ func _() {
f.Baz() //@snippet("B", snipMethodBazBaz, "BazBaz(${1:})", "BazBaz(${1:at AliasType})")
}
func _() {
type bar struct {
a int
b float64 //@item(snipBarB, "b", "float64", "field")
}
bar{b} //@snippet("}", snipBarB, "b: ${1:}", "b: ${1:float64}")
}

View File

@ -2,7 +2,7 @@
CallHierarchyCount = 2
CodeLensCount = 5
CompletionsCount = 258
CompletionSnippetCount = 89
CompletionSnippetCount = 90
UnimportedCompletionsCount = 5
DeepCompletionsCount = 5
FuzzyCompletionsCount = 8