gopls/internal/analysis/fillstruct: don't panic with invalid fields
Fixes golang/go#63921
Change-Id: Ic7c310f39cd92c93b9fd6cc78a35ab88ba6b3f7b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/549116
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/gopls/internal/analysis/fillstruct/fillstruct.go b/gopls/internal/analysis/fillstruct/fillstruct.go
index 1230a87..4b1bb4a 100644
--- a/gopls/internal/analysis/fillstruct/fillstruct.go
+++ b/gopls/internal/analysis/fillstruct/fillstruct.go
@@ -345,6 +345,8 @@
//
// The reasoning here is that users will call fillstruct with the intention of
// initializing the struct, in which case setting these fields to nil has no effect.
+//
+// populateValue returns nil if the value cannot be filled.
func populateValue(f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
switch u := typ.Underlying().(type) {
case *types.Basic:
@@ -357,6 +359,8 @@
return &ast.BasicLit{Kind: token.STRING, Value: `""`}
case u.Kind() == types.UnsafePointer:
return ast.NewIdent("nil")
+ case u.Kind() == types.Invalid:
+ return nil
default:
panic(fmt.Sprintf("unknown basic type %v", u))
}
@@ -478,9 +482,13 @@
},
}
default:
+ x := populateValue(f, pkg, u.Elem())
+ if x == nil {
+ return nil
+ }
return &ast.UnaryExpr{
Op: token.AND,
- X: populateValue(f, pkg, u.Elem()),
+ X: x,
}
}
diff --git a/gopls/internal/test/marker/testdata/codeaction/fill_struct.txt b/gopls/internal/test/marker/testdata/codeaction/fill_struct.txt
index 4e798a5..092a427 100644
--- a/gopls/internal/test/marker/testdata/codeaction/fill_struct.txt
+++ b/gopls/internal/test/marker/testdata/codeaction/fill_struct.txt
@@ -558,3 +558,17 @@
+ _ = S{
+ t: *new(T),
+ } //@codeactionedit("}", "refactor.rewrite", typeparams5)
+-- issue63921.go --
+package fillstruct
+
+// Test for golang/go#63921: fillstruct panicked with invalid fields.
+type invalidStruct struct {
+ F int
+ Undefined
+}
+
+func _() {
+ // Note: the golden content for issue63921 is empty: fillstruct produces no
+ // edits, but does not panic.
+ invalidStruct{} //@codeactionedit("}", "refactor.rewrite", issue63921)
+}