diff --git a/gen/decode.go b/gen/decode.go index 6e1af0ee..2b6a6f38 100644 --- a/gen/decode.go +++ b/gen/decode.go @@ -201,7 +201,7 @@ func (d *decodeGen) structAsTuple(s *Struct) { d.p.declare(sz, u32) d.assignArray(sz, arrayHeader, 0) if s.AsVarTuple { - d.p.printf("\nif %[1]s == 0 { return }", sz) + d.p.printf("\nfor %[1]s > 0 {", sz) // start the block } else { d.p.arrayCheck(strconv.Itoa(len(s.Fields)), sz) } @@ -239,11 +239,12 @@ func (d *decodeGen) structAsTuple(s *Struct) { d.p.printf("\n}") // close if statement } if s.AsVarTuple { - d.p.printf("\nif %[1]s--; %[1]s == 0 { return }", sz) + d.p.printf("\nif %[1]s--; %[1]s == 0 { break }", sz) // exit from the block } } if s.AsVarTuple { d.p.printf("\nfor ; %[1]s > 0; %[1]s-- {\nif err = dc.Skip(); err != nil {\nerr = msgp.WrapError(err)\nreturn\n}\n}", sz) + d.p.printf("\n}") // end the block } } diff --git a/gen/unmarshal.go b/gen/unmarshal.go index f74b6180..21f30b54 100644 --- a/gen/unmarshal.go +++ b/gen/unmarshal.go @@ -223,7 +223,7 @@ func (u *unmarshalGen) tuple(s *Struct) { u.p.declare(sz, u32) u.assignAndCheck(sz, arrayHeader) if s.AsVarTuple { - u.p.printf("\nif %[1]s == 0 {\no = bts\nreturn\n}", sz) + u.p.printf("\nfor %[1]s > 0 {", sz) // start the block } else { u.p.arrayCheck(strconv.Itoa(len(s.Fields)), sz) } @@ -265,11 +265,12 @@ func (u *unmarshalGen) tuple(s *Struct) { u.p.printf("\n}") } if s.AsVarTuple { - u.p.printf("\nif %[1]s--; %[1]s == 0 {\no = bts\nreturn\n}", sz) + u.p.printf("\nif %[1]s--; %[1]s == 0 { break }", sz) // exit from the block } } if s.AsVarTuple { u.p.printf("\nfor ; %[1]s > 0; %[1]s-- {\nbts, err = msgp.Skip(bts)\nif err != nil {\nerr = msgp.WrapError(err)\nreturn\n}\n}", sz) + u.p.printf("\n}") // end the block } } diff --git a/issue430_test.go b/issue430_test.go new file mode 100644 index 00000000..55ac026d --- /dev/null +++ b/issue430_test.go @@ -0,0 +1,60 @@ +package main + +import "testing" + +func TestIssue430Nested(t *testing.T) { + mainFilename, err := generate(t, issue430Nested) + if err != nil { + t.Fatalf("generate failed: %v", err) + } + + goExec(t, mainFilename, false) // exec go run + goExec(t, mainFilename, true) // exec go test +} + +var issue430Nested = `package main + +import ( + "fmt" + "os" +) + +//go:generate msgp + +//msgp:vartuple Bag +type Bag struct { + ItemID uint32 + ItemNum uint32 +} + +//msgp:vartuple User +type User struct { + Name string + Bag []*Bag +} + +func main() { + u := User{Name: "user", Bag: []*Bag{{1, 2}, {3, 4}}} + data, err := u.MarshalMsg(nil) + if err != nil { + fmt.Println("User MarshalMsg failed:", err) + os.Exit(1) + } + + var user User + if _, err := user.UnmarshalMsg(data); err != nil { + fmt.Println("User UnmarshalMsg failed:", err) + os.Exit(1) + } + if user.Name != "user" || + user.Bag[0] == nil || + user.Bag[0].ItemID != 1 || + user.Bag[0].ItemNum != 2 || + user.Bag[1] == nil || + user.Bag[1].ItemID != 3 || + user.Bag[1].ItemNum != 4 { + fmt.Println("User UnmarshalMsg bad user:", user) + os.Exit(1) + } +} +`