go/analysis/passes/loopclosure: add typeparams test
testdata/src/typeparams is similar to testdata/src/a but
uses type parameters.
Change-Id: Ia92f146089da4b1a3743c265181127ca886a71ad
Reviewed-on: https://go-review.googlesource.com/c/tools/+/354701
Trust: Guodong Li <guodongli@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/go/analysis/passes/loopclosure/loopclosure_test.go b/go/analysis/passes/loopclosure/loopclosure_test.go
index 0916f5e..1498838 100644
--- a/go/analysis/passes/loopclosure/loopclosure_test.go
+++ b/go/analysis/passes/loopclosure/loopclosure_test.go
@@ -5,6 +5,7 @@
package loopclosure_test
import (
+ "golang.org/x/tools/internal/typeparams"
"testing"
"golang.org/x/tools/go/analysis/analysistest"
@@ -13,5 +14,9 @@
func Test(t *testing.T) {
testdata := analysistest.TestData()
- analysistest.Run(t, testdata, loopclosure.Analyzer, "a")
+ tests := []string{"a", "golang.org/..."}
+ if typeparams.Enabled {
+ tests = append(tests, "typeparams")
+ }
+ analysistest.Run(t, testdata, loopclosure.Analyzer, tests...)
}
diff --git a/go/analysis/passes/loopclosure/testdata/src/typeparams/typeparams.go b/go/analysis/passes/loopclosure/testdata/src/typeparams/typeparams.go
new file mode 100644
index 0000000..55e129c
--- /dev/null
+++ b/go/analysis/passes/loopclosure/testdata/src/typeparams/typeparams.go
@@ -0,0 +1,60 @@
+// 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 loopclosure checker.
+
+//go:build go1.18
+
+package typeparams
+
+import "golang.org/x/sync/errgroup"
+
+func f[T any](data T) {
+ print(data)
+}
+
+func _[T any]() {
+ var s []T
+ for i, v := range s {
+ go func() {
+ f(i) // want "loop variable i captured by func literal"
+ f(v) // want "loop variable v captured by func literal"
+ }()
+ }
+}
+
+func loop[P interface{ Go(func() error) }](grp P) {
+ var s []int
+ for i, v := range s {
+ // The checker only matches on methods "(*...errgroup.Group).Go".
+ grp.Go(func() error {
+ print(i)
+ print(v)
+ return nil
+ })
+ }
+}
+
+func _() {
+ g := new(errgroup.Group)
+ loop(g) // the analyzer is not "type inter-procedural" so no findings are reported
+}
+
+type T[P any] struct {
+ a P
+}
+
+func (t T[P]) Go(func() error) { }
+
+func _(g T[errgroup.Group]) {
+ var s []int
+ for i, v := range s {
+ // "T.a" is method "(*...errgroup.Group).Go".
+ g.a.Go(func() error {
+ print(i) // want "loop variable i captured by func literal"
+ print(v) // want "loop variable v captured by func literal"
+ return nil
+ })
+ }
+}
\ No newline at end of file