cmd/go: produce a better error for generic test functions

Test functions with type parameters cannot be invoked without type
arguments, so cmd/go would previously fail with a type-checking error in
the test harness.

Avoid this by producing an error explaining that test functions cannot
have type parameters.

Fixes #48953

Change-Id: I4e39c9b7a06c964fad5f12d74d262aa090c25d79
Reviewed-on: https://go-review.googlesource.com/c/go/+/355889
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/src/cmd/go/internal/load/test.go b/src/cmd/go/internal/load/test.go
index da6d1cb..4cefb62 100644
--- a/src/cmd/go/internal/load/test.go
+++ b/src/cmd/go/internal/load/test.go
@@ -678,10 +678,16 @@
 }
 
 func checkTestFunc(fn *ast.FuncDecl, arg string) error {
+	var why string
 	if !isTestFunc(fn, arg) {
-		name := fn.Name.String()
+		why = fmt.Sprintf("must be: func %s(%s *testing.%s)", fn.Name.String(), strings.ToLower(arg), arg)
+	}
+	if fn.Type.TypeParams.NumFields() > 0 {
+		why = "test functions cannot have type parameters"
+	}
+	if why != "" {
 		pos := testFileSet.Position(fn.Pos())
-		return fmt.Errorf("%s: wrong signature for %s, must be: func %s(%s *testing.%s)", pos, name, name, strings.ToLower(arg), arg)
+		return fmt.Errorf("%s: wrong signature for %s, %s", pos, fn.Name.String(), why)
 	}
 	return nil
 }
diff --git a/src/cmd/go/testdata/script/list_test_err.txt b/src/cmd/go/testdata/script/list_test_err.txt
index c6f1ecf..25dbb96 100644
--- a/src/cmd/go/testdata/script/list_test_err.txt
+++ b/src/cmd/go/testdata/script/list_test_err.txt
@@ -44,6 +44,10 @@
 stdout 'nameerr\.test "[^"]*wrong signature for TestBad'
 ! stderr 'wrong signature for TestBad'
 
+# go list prints a useful error for generic test functions
+! go list -test -deps genericerr
+stderr 'wrong signature for TestGeneric, test functions cannot have type parameters'
+
 # go list prints partial information with error if test has cyclic import
 ! go list -test -deps cycleerr
 stdout cycleerr
@@ -106,6 +110,16 @@
 
 func TestBad(t *testing.B) {}
 
+-- genericerr/genericerr.go --
+package genericerr
+
+-- genericerr/genericerr_test.go --
+package genericerr
+
+import "testing"
+
+func TestGeneric[T any](t *testing.T) {}
+
 -- cycleerr/cycleerr_test.go --
 package cycleerr