internal/lsp: disable fillstruct for type params
Do not suggest fixes for types that require type params
or that have fields that require type parameters.
Change-Id: I68059956a7d38be0ffa3f79230615437ccc5788f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/353109
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Suzy Mueller <suzmue@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/internal/lsp/analysis/fillstruct/fillstruct.go b/internal/lsp/analysis/fillstruct/fillstruct.go
index 0547288..a4dd8cc 100644
--- a/internal/lsp/analysis/fillstruct/fillstruct.go
+++ b/internal/lsp/analysis/fillstruct/fillstruct.go
@@ -22,6 +22,7 @@
"golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/internal/analysisinternal"
"golang.org/x/tools/internal/span"
+ "golang.org/x/tools/internal/typeparams"
)
const Doc = `note incomplete struct initializations
@@ -66,6 +67,14 @@
return
}
+ // Ignore types that have type parameters for now.
+ // TODO: support type params.
+ if typ, ok := typ.(*types.Named); ok {
+ if tparams := typeparams.ForNamed(typ); tparams != nil && tparams.Len() > 0 {
+ return
+ }
+ }
+
// Find reference to the type declaration of the struct being initialized.
for {
p, ok := typ.Underlying().(*types.Pointer)
@@ -95,6 +104,16 @@
if field.Pkg() != nil && field.Pkg() != pass.Pkg && !field.Exported() {
continue
}
+ // Ignore structs containing fields that have type parameters for now.
+ // TODO: support type params.
+ if typ, ok := field.Type().(*types.Named); ok {
+ if tparams := typeparams.ForNamed(typ); tparams != nil && tparams.Len() > 0 {
+ return
+ }
+ }
+ if _, ok := field.Type().(*typeparams.TypeParam); ok {
+ return
+ }
fillable = true
fillableFields = append(fillableFields, fmt.Sprintf("%s: %s", field.Name(), field.Type().String()))
}
diff --git a/internal/lsp/analysis/fillstruct/fillstruct_test.go b/internal/lsp/analysis/fillstruct/fillstruct_test.go
index 34c9923e..51a516c 100644
--- a/internal/lsp/analysis/fillstruct/fillstruct_test.go
+++ b/internal/lsp/analysis/fillstruct/fillstruct_test.go
@@ -9,9 +9,14 @@
"golang.org/x/tools/go/analysis/analysistest"
"golang.org/x/tools/internal/lsp/analysis/fillstruct"
+ "golang.org/x/tools/internal/typeparams"
)
func Test(t *testing.T) {
testdata := analysistest.TestData()
- analysistest.Run(t, testdata, fillstruct.Analyzer, "a")
+ tests := []string{"a"}
+ if typeparams.Enabled {
+ tests = append(tests, "typeparams")
+ }
+ analysistest.Run(t, testdata, fillstruct.Analyzer, tests...)
}
diff --git a/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typeparams.go b/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typeparams.go
new file mode 100644
index 0000000..9029061
--- /dev/null
+++ b/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typeparams.go
@@ -0,0 +1,41 @@
+// Copyright 2020 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.
+
+package fillstruct
+
+type emptyStruct[A any] struct{}
+
+var _ = emptyStruct[int]{}
+
+type basicStruct[T any] struct {
+ foo T
+}
+
+var _ = basicStruct[int]{}
+
+type fooType[T any] T
+
+type twoArgStruct[F, B any] struct {
+ foo fooType[F]
+ bar fooType[B]
+}
+
+var _ = twoArgStruct[string, int]{}
+
+var _ = twoArgStruct[int, string]{
+ bar: "bar",
+}
+
+type nestedStruct struct {
+ bar string
+ basic basicStruct[int]
+}
+
+var _ = nestedStruct{}
+
+func _[T any]() {
+ type S struct{ t T }
+ x := S{}
+ _ = x
+}