internal/lsp/completion: fix untyped int type inference

For index expressions, optional "make" args, and composite literal
slice/array keys, we were inferring an expected type of int instead of
untyped int. This caused candidate rankings to not be quite right in
general, and in particular, after support for automatic type
conversions was added, the issue manifested as:

    var foo []int
    var bar int32
    foo[ba<>] // completed to "int(bar)" instead of "bar"

Fixes golang/go#43375.

Change-Id: I6daef7d23b767f296bdbbc8f47f5b2c972ad9b80
Reviewed-on: https://go-review.googlesource.com/c/tools/+/289272
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-03 13:24:46 -08:00 committed by Rebecca Stambler
parent b30482dd32
commit ef80cdb6ec
5 changed files with 14 additions and 6 deletions

View File

@ -127,7 +127,7 @@ func (c *completer) builtinArgType(obj types.Object, call *ast.CallExpr, parentI
inf.typeName.wantTypeName = true
inf.objType = parentInf.objType
} else {
inf.objType = types.Typ[types.Int]
inf.objType = types.Typ[types.UntypedInt]
}
}

View File

@ -1690,12 +1690,12 @@ func (c *completer) expectedCompositeLiteralType() types.Type {
switch t := clInfo.clType.(type) {
case *types.Slice:
if clInfo.inKey {
return types.Typ[types.Int]
return types.Typ[types.UntypedInt]
}
return t.Elem()
case *types.Array:
if clInfo.inKey {
return types.Typ[types.Int]
return types.Typ[types.UntypedInt]
}
return t.Elem()
case *types.Map:
@ -2038,7 +2038,7 @@ Nodes:
case *ast.SliceExpr:
// Make sure position falls within the brackets (e.g. "foo[a:<>]").
if node.Lbrack < c.pos && c.pos <= node.Rbrack {
inf.objType = types.Typ[types.Int]
inf.objType = types.Typ[types.UntypedInt]
}
return inf
case *ast.IndexExpr:
@ -2049,7 +2049,7 @@ Nodes:
case *types.Map:
inf.objType = t.Key()
case *types.Slice, *types.Array:
inf.objType = types.Typ[types.Int]
inf.objType = types.Typ[types.UntypedInt]
}
}
}

View File

@ -43,6 +43,10 @@ func _() {
make() //@rank(")", builtinMapType, int),rank(")", builtinChanType, int),rank(")", builtinSliceType, int),rank(")", builtinMapType, int)
make(aSliceType, a) //@rank(")", builtinInt, builtinSlice)
type myInt int
var mi myInt //@item(builtinMyInt, "mi", "myInt", "var")
make(aSliceType, m) //@snippet(")", builtinMyInt, "mi", "mi")
var _ []int = make() //@rank(")", builtinSliceType, builtinMapType)
type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct")

View File

@ -18,4 +18,8 @@ func _() {
type myMap map[string]int
var baz myMap
baz[a] //@complete("]", indexAA, indexAB)
type myInt int
var mi myInt //@item(indexMyInt, "mi", "myInt", "var")
foo[m] //@snippet("]", indexMyInt, "mi", "mi")
}

View File

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