internal/typesinternal: add TupleOf helper

...and use it in go/ssa and unusedresult.

Change-Id: Id77f478d0a0f9e37bcf46033f14c3f126f02ca11
Reviewed-on: https://go-review.googlesource.com/c/tools/+/804460
Auto-Submit: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alex Putman <aputman@golang.org>
diff --git a/go/analysis/passes/unusedresult/unusedresult.go b/go/analysis/passes/unusedresult/unusedresult.go
index bd32d58..82968f4 100644
--- a/go/analysis/passes/unusedresult/unusedresult.go
+++ b/go/analysis/passes/unusedresult/unusedresult.go
@@ -16,7 +16,6 @@
 import (
 	_ "embed"
 	"go/ast"
-	"go/token"
 	"go/types"
 	"sort"
 	"strings"
@@ -27,6 +26,7 @@
 	"golang.org/x/tools/go/types/typeutil"
 	"golang.org/x/tools/internal/analysis/analyzerutil"
 	"golang.org/x/tools/internal/astutil"
+	"golang.org/x/tools/internal/typesinternal"
 )
 
 //go:embed doc.go
@@ -172,7 +172,7 @@
 }
 
 // func() string
-var sigNoArgsStringResult = types.NewSignatureType(nil, nil, nil, nil, types.NewTuple(types.NewParam(token.NoPos, nil, "", types.Typ[types.String])), false)
+var sigNoArgsStringResult = types.NewSignatureType(nil, nil, nil, nil, typesinternal.TupleOf(types.Typ[types.String]), false)
 
 type stringSetFlag map[string]bool
 
diff --git a/go/ssa/builder.go b/go/ssa/builder.go
index 1669d80..a663af8 100644
--- a/go/ssa/builder.go
+++ b/go/ssa/builder.go
@@ -85,6 +85,7 @@
 	"slices"
 
 	"golang.org/x/tools/internal/typeparams"
+	"golang.org/x/tools/internal/typesinternal"
 	"golang.org/x/tools/internal/versions"
 )
 
@@ -124,7 +125,7 @@
 	// The ssa:deferstack intrinsic returns the current function's defer stack.
 	vDeferStack = &Builtin{
 		name: "ssa:deferstack",
-		sig:  types.NewSignatureType(nil, nil, nil, nil, types.NewTuple(anonVar(tDeferStack)), false),
+		sig:  types.NewSignatureType(nil, nil, nil, nil, typesinternal.TupleOf(tDeferStack), false),
 	}
 )
 
@@ -1719,7 +1720,7 @@
 	for _, st := range states {
 		if st.Dir == types.RecvOnly {
 			chtyp := typeparams.CoreType(fn.typ(st.Chan.Type())).(*types.Chan)
-			vars = append(vars, anonVar(chtyp.Elem()))
+			vars = append(vars, newVar("", chtyp.Elem()))
 		}
 	}
 	sel.setType(types.NewTuple(vars...))
diff --git a/go/ssa/util.go b/go/ssa/util.go
index 42f9621..5dfca72 100644
--- a/go/ssa/util.go
+++ b/go/ssa/util.go
@@ -181,19 +181,13 @@
 	return types.NewParam(token.NoPos, nil, name, typ)
 }
 
-// anonVar creates an anonymous 'var' for use in a types.Tuple.
-func anonVar(typ types.Type) *types.Var {
-	return newVar("", typ)
-}
-
-var lenResults = types.NewTuple(anonVar(tInt))
+var lenResults = typesinternal.TupleOf(tInt)
 
 // makeLen returns the len builtin specialized to type func(T)int.
 func makeLen(T types.Type) *Builtin {
-	lenParams := types.NewTuple(anonVar(T))
 	return &Builtin{
 		name: "len",
-		sig:  types.NewSignatureType(nil, nil, nil, lenParams, lenResults, false),
+		sig:  types.NewSignatureType(nil, nil, nil, typesinternal.TupleOf(T), lenResults, false),
 	}
 }
 
diff --git a/go/ssa/wrappers.go b/go/ssa/wrappers.go
index 6cadd04..fbb0674 100644
--- a/go/ssa/wrappers.go
+++ b/go/ssa/wrappers.go
@@ -26,6 +26,7 @@
 	"go/types"
 
 	"golang.org/x/tools/internal/typeparams"
+	"golang.org/x/tools/internal/typesinternal"
 )
 
 // -- wrappers -----------------------------------------------------------
@@ -118,10 +119,12 @@
 		// For simple indirection wrappers, perform an informative nil-check:
 		// "value method (T).f called using nil *T pointer"
 		if len(indices) == 1 && !isPointer(recvType(fn.object)) {
+			params := typesinternal.TupleOf(fn.method.recv, tString, tString)
+			results := typesinternal.TupleOf(fn.method.recv)
 			var c Call
 			c.Call.Value = &Builtin{
 				name: "ssa:wrapnilchk",
-				sig:  types.NewSignatureType(nil, nil, nil, types.NewTuple(anonVar(fn.method.recv), anonVar(tString), anonVar(tString)), types.NewTuple(anonVar(fn.method.recv)), false),
+				sig:  types.NewSignatureType(nil, nil, nil, params, results, false),
 			}
 			c.Call.Args = []Value{
 				v,
diff --git a/internal/typesinternal/types.go b/internal/typesinternal/types.go
index d2c0b4c..9fd48b0 100644
--- a/internal/typesinternal/types.go
+++ b/internal/typesinternal/types.go
@@ -270,3 +270,11 @@
 		}
 	}
 }
+
+func TupleOf(elems ...types.Type) *types.Tuple {
+	params := make([]*types.Var, len(elems))
+	for i, elem := range elems {
+		params[i] = types.NewParam(token.NoPos, nil, "", elem)
+	}
+	return types.NewTuple(params...)
+}