lsp/completion: improve completion for func type params

Now when instantiating a generic function, we prefer type names that
are assignable to the corresponding constraint. For example:

    func foo[A int|string]() {}

    foo[<>]()

At <> we prefer the type names "int" and "string". Previously we had
no preference at all.

Updates golang/go#51782.

Change-Id: I7ed39ffa2bc4c63e9d320f47a58e139251712bb3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/394014
Run-TryBot: Muir Manders <muir@mnd.rs>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go
index 9088616..8d4df6b 100644
--- a/internal/lsp/source/completion/completion.go
+++ b/internal/lsp/source/completion/completion.go
@@ -29,6 +29,7 @@
 	"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 @@
 						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 284ef64..71a53d9 100644
--- a/internal/lsp/testdata/summary_go1.18.txt.golden
+++ b/internal/lsp/testdata/summary_go1.18.txt.golden
@@ -6,7 +6,7 @@
 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 0000000..4636dfa
--- /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)
+}