lsp/completion: further improve generic func arg ranking

In cases like:

    func foo[T int | string](T) {}
    foo[int](<>)

Previously at <> we would favor int and string candidates. This is
because go/types doesn't instantiate foo in this case (for some
reason). Work around the issue by using types.CheckExpr to re-check
the *ast.CallExpr.Fun. CheckExpr seems to do a better than a full type
check in the face of errors.

Updates golang/go#52291
Updates golang/go#52503

Change-Id: Ide436428f3232db2e06ea3cc22ea250edbf28685
Reviewed-on: https://go-review.googlesource.com/c/tools/+/400614
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go
index 089c373..32d5370 100644
--- a/internal/lsp/source/completion/completion.go
+++ b/internal/lsp/source/completion/completion.go
@@ -2002,7 +2002,22 @@
 					break Nodes
 				}
 
-				if sig, _ := c.pkg.GetTypesInfo().Types[node.Fun].Type.(*types.Signature); sig != nil {
+				sig, _ := c.pkg.GetTypesInfo().Types[node.Fun].Type.(*types.Signature)
+
+				if sig != nil && typeparams.ForSignature(sig).Len() > 0 {
+					// If we are completing a generic func call, re-check the call expression.
+					// This allows type param inference to work in cases like:
+					//
+					// func foo[T any](T) {}
+					// foo[int](<>) // <- get "int" completions instead of "T"
+					//
+					// TODO: remove this after https://go.dev/issue/52503
+					info := &types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
+					types.CheckExpr(c.snapshot.FileSet(), c.pkg.GetTypes(), node.Fun.Pos(), node.Fun, info)
+					sig, _ = info.Types[node.Fun].Type.(*types.Signature)
+				}
+
+				if sig != nil {
 					inf = c.expectedCallParamType(inf, node, sig)
 				}
 
diff --git a/internal/lsp/testdata/typeparams/type_params.go b/internal/lsp/testdata/typeparams/type_params.go
index 34a2a6b..f048027 100644
--- a/internal/lsp/testdata/typeparams/type_params.go
+++ b/internal/lsp/testdata/typeparams/type_params.go
@@ -32,6 +32,6 @@
 	var _ int = returnTP //@snippet(" //", returnTP, "returnTP[${1:}](${2:})", "returnTP[${1:A int|float64}](${2:a A})")
 
 	var aa int //@item(tpInt, "aa", "int", "var")
-	var ab string //@item(tpString, "ab", "string", "var")
-	returnTP[int](a) //@rank(")", tpInt, tpString)
+	var ab float64 //@item(tpFloat, "ab", "float64", "var")
+	returnTP[int](a) //@rank(")", tpInt, tpFloat)
 }