Skip to content

Commit 89082a3

Browse files
muirdmstamblerre
authored andcommitted
internal/lsp/source: fix some invalid literal candidates
We were marking all literal candidates as addressable so we were getting invalid candidates like "&int()". Fix it to only mark literal struct, array, slice and map types as addressable. I also fixed the unnamed literal candidate to pass the dereferenced expected type. For example, if the expected type was "*[]int" we were passing a literal type of "*[]int" which wasn't working anymore. Now we pass "[]int" and take its address as "&[]int{}". Change-Id: I5d0ee074d3cc91c39dd881630583e31be5a05579 Reviewed-on: https://go-review.googlesource.com/c/tools/+/212677 Run-TryBot: Muir Manders <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]>
1 parent 316d2f2 commit 89082a3

File tree

4 files changed

+21
-6
lines changed

4 files changed

+21
-6
lines changed

internal/lsp/source/completion.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -917,8 +917,9 @@ func (c *completer) lexical() error {
917917
// if an object literal makes a good candidate. For example, if
918918
// our expected type is "[]int", this will add a candidate of
919919
// "[]int{}".
920-
if _, named := deref(c.expectedType.objType).(*types.Named); !named {
921-
c.literal(c.expectedType.objType, nil)
920+
t := deref(c.expectedType.objType)
921+
if _, named := t.(*types.Named); !named {
922+
c.literal(t, nil)
922923
}
923924
}
924925

internal/lsp/source/completion_literal.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,16 @@ func (c *completer) literal(literalType types.Type, imp *importInfo) {
6565

6666
// Check if an object of type literalType would match our expected type.
6767
cand := candidate{
68-
obj: c.fakeObj(literalType),
69-
addressable: true,
68+
obj: c.fakeObj(literalType),
7069
}
70+
71+
switch literalType.Underlying().(type) {
72+
// These literal types are addressable (e.g. "&[]int{}"), others are
73+
// not (e.g. can't do "&(func(){})").
74+
case *types.Struct, *types.Array, *types.Slice, *types.Map:
75+
cand.addressable = true
76+
}
77+
7178
if !c.matchingCandidate(&cand) {
7279
return
7380
}

internal/lsp/testdata/snippets/literal_snippets.go.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ import (
1010

1111
func _() {
1212
[]int{} //@item(litIntSlice, "[]int{}", "", "var")
13+
&[]int{} //@item(litIntSliceAddr, "&[]int{}", "", "var")
1314
make([]int, 0) //@item(makeIntSlice, "make([]int, 0)", "", "func")
1415

16+
var _ *[]int = in //@snippet(" //", litIntSliceAddr, "&[]int{$0\\}", "&[]int{$0\\}")
17+
var _ **[]int = in //@complete(" //")
18+
1519
var slice []int
1620
slice = i //@snippet(" //", litIntSlice, "[]int{$0\\}", "[]int{$0\\}")
1721
slice = m //@snippet(" //", makeIntSlice, "make([]int, ${1:})", "make([]int, ${1:0})")
@@ -164,6 +168,9 @@ func _() {
164168
func _() {
165169
float64() //@item(litFloat64, "float64()", "float64", "var")
166170

171+
// don't complete to "&float64()"
172+
var _ *float64 = float64 //@complete(" //")
173+
167174
var f float64
168175
f = fl //@complete(" //", litFloat64),snippet(" //", litFloat64, "float64($0)", "float64($0)")
169176

internal/lsp/testdata/summary.txt.golden

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
-- summary --
2-
CompletionsCount = 223
3-
CompletionSnippetCount = 61
2+
CompletionsCount = 225
3+
CompletionSnippetCount = 62
44
UnimportedCompletionsCount = 4
55
DeepCompletionsCount = 5
66
FuzzyCompletionsCount = 8

0 commit comments

Comments
 (0)