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