diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go index 90886167ab..8d4df6bab9 100644 --- a/internal/lsp/source/completion/completion.go +++ b/internal/lsp/source/completion/completion.go @@ -29,6 +29,7 @@ import ( "golang.org/x/tools/internal/lsp/protocol" "golang.org/x/tools/internal/lsp/snippet" "golang.org/x/tools/internal/lsp/source" + "golang.org/x/tools/internal/typeparams" errors "golang.org/x/xerrors" ) @@ -2093,6 +2094,25 @@ Nodes: inf.objType = t.Key() case *types.Slice, *types.Array: inf.objType = types.Typ[types.UntypedInt] + case *types.Signature: + if tp := typeparams.ForSignature(t); tp.Len() > 0 { + inf.objType = tp.At(0).Constraint() + inf.typeName.wantTypeName = true + } + } + } + } + return inf + case *typeparams.IndexListExpr: + if node.Lbrack < c.pos && c.pos <= node.Rbrack { + if tv, ok := c.pkg.GetTypesInfo().Types[node.X]; ok { + switch t := tv.Type.Underlying().(type) { + case *types.Signature: + paramIdx := exprAtPos(c.pos, node.Indices) + if tp := typeparams.ForSignature(t); paramIdx < tp.Len() { + inf.objType = tp.At(paramIdx).Constraint() + inf.typeName.wantTypeName = true + } } } } diff --git a/internal/lsp/testdata/summary_go1.18.txt.golden b/internal/lsp/testdata/summary_go1.18.txt.golden index 284ef645e1..71a53d9af5 100644 --- a/internal/lsp/testdata/summary_go1.18.txt.golden +++ b/internal/lsp/testdata/summary_go1.18.txt.golden @@ -6,7 +6,7 @@ CompletionSnippetCount = 109 UnimportedCompletionsCount = 5 DeepCompletionsCount = 5 FuzzyCompletionsCount = 8 -RankedCompletionsCount = 163 +RankedCompletionsCount = 166 CaseSensitiveCompletionsCount = 4 DiagnosticsCount = 37 FoldingRangesCount = 2 diff --git a/internal/lsp/testdata/typeparams/type_params.go b/internal/lsp/testdata/typeparams/type_params.go new file mode 100644 index 0000000000..4636dfa8e7 --- /dev/null +++ b/internal/lsp/testdata/typeparams/type_params.go @@ -0,0 +1,13 @@ +//go:build go1.18 +// +build go1.18 + +package typeparams + +func one[a int | string]() {} +func two[a int | string, b float64 | int]() {} + +func _() { + one[]() //@rank("]", string, float64) + two[]() //@rank("]", int, float64) + two[int, f]() //@rank("]", float64, float32) +}