From e46688f41326d03a6df28607f1b4d170e31b16ad Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Tue, 12 Dec 2023 10:35:42 -0500 Subject: [PATCH] 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 LUCI-TryBot-Result: Go LUCI --- gopls/internal/analysis/fillstruct/fillstruct.go | 10 +++++++++- .../marker/testdata/codeaction/fill_struct.txt | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/gopls/internal/analysis/fillstruct/fillstruct.go b/gopls/internal/analysis/fillstruct/fillstruct.go index 1230a87ff44..4b1bb4aa4b0 100644 --- a/gopls/internal/analysis/fillstruct/fillstruct.go +++ b/gopls/internal/analysis/fillstruct/fillstruct.go @@ -345,6 +345,8 @@ func indent(str, ind []byte) []byte { // // 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 @@ func populateValue(f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { 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 @@ func populateValue(f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { }, } 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 4e798a55fd6..092a4275ffb 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 @@ func _[T any]() { + _ = 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) +}