go/analysis/passes/deepequalerrors: add typeparams test

This CL adds a test for the assign pass that involves use of generics.

Update golang/go#48704

Change-Id: I1aa51aed24d63d42b6b0150d64925b97dfd59a92
Reviewed-on: https://go-review.googlesource.com/c/tools/+/357412
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Trust: Cherry Mui <cherryyz@google.com>
diff --git a/go/analysis/passes/deepequalerrors/deepequalerrors_test.go b/go/analysis/passes/deepequalerrors/deepequalerrors_test.go
index 2d4faa3..0094173 100644
--- a/go/analysis/passes/deepequalerrors/deepequalerrors_test.go
+++ b/go/analysis/passes/deepequalerrors/deepequalerrors_test.go
@@ -9,9 +9,14 @@
 
 	"golang.org/x/tools/go/analysis/analysistest"
 	"golang.org/x/tools/go/analysis/passes/deepequalerrors"
+	"golang.org/x/tools/internal/typeparams"
 )
 
 func Test(t *testing.T) {
 	testdata := analysistest.TestData()
-	analysistest.Run(t, testdata, deepequalerrors.Analyzer, "a")
+	tests := []string{"a"}
+	if typeparams.Enabled {
+		tests = append(tests, "typeparams")
+	}
+	analysistest.Run(t, testdata, deepequalerrors.Analyzer, tests...)
 }
diff --git a/go/analysis/passes/deepequalerrors/testdata/src/typeparams/typeparams.go b/go/analysis/passes/deepequalerrors/testdata/src/typeparams/typeparams.go
new file mode 100644
index 0000000..ac16aa3
--- /dev/null
+++ b/go/analysis/passes/deepequalerrors/testdata/src/typeparams/typeparams.go
@@ -0,0 +1,58 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests for the deepequalerrors checker.
+
+package a
+
+import (
+	"io"
+	"os"
+	"reflect"
+)
+
+type myError int
+
+func (myError) Error() string { return "" }
+
+func bad[T any]() T {
+	var t T
+	return t
+}
+
+type s1 struct {
+	s2 *s2[myError2]
+	i  int
+}
+
+type myError2 error
+
+type s2[T any] struct {
+	s1   *s1
+	errs []*T
+}
+
+func hasError() {
+	var e error
+	var m myError2
+	reflect.DeepEqual(bad[error](), e)    // want `avoid using reflect.DeepEqual with errors`
+	reflect.DeepEqual(io.EOF, io.EOF)     // want `avoid using reflect.DeepEqual with errors`
+	reflect.DeepEqual(e, &e)              // want `avoid using reflect.DeepEqual with errors`
+	reflect.DeepEqual(e, m)               // want `avoid using reflect.DeepEqual with errors`
+	reflect.DeepEqual(e, s1{})            // want `avoid using reflect.DeepEqual with errors`
+	reflect.DeepEqual(e, [1]error{})      // want `avoid using reflect.DeepEqual with errors`
+	reflect.DeepEqual(e, map[error]int{}) // want `avoid using reflect.DeepEqual with errors`
+	reflect.DeepEqual(e, map[int]error{}) // want `avoid using reflect.DeepEqual with errors`
+	// We catch the next not because *os.PathError implements error, but because it contains
+	// a field Err of type error.
+	reflect.DeepEqual(&os.PathError{}, io.EOF) // want `avoid using reflect.DeepEqual with errors`
+
+}
+
+func notHasError() {
+	reflect.ValueOf(4)                    // not reflect.DeepEqual
+	reflect.DeepEqual(3, 4)               // not errors
+	reflect.DeepEqual(5, io.EOF)          // only one error
+	reflect.DeepEqual(myError(1), io.EOF) // not types that implement error
+}