Skip to content

Commit

Permalink
Fix allownil on maps elements (#375)
Browse files Browse the repository at this point in the history
* Fix allownil on maps elements
* Also set for primitives.

Similar to #374 map `[]byte` elements would also inherit allownil unintentionally.
  • Loading branch information
klauspost authored Oct 22, 2024
1 parent 65798b6 commit 4558fbf
Show file tree
Hide file tree
Showing 7 changed files with 13 additions and 6 deletions.
3 changes: 3 additions & 0 deletions _generated/allownil.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,6 @@ type AllowNilOmitEmpty2 struct {
Field00 []string `msg:"field00,allownil,omitempty"`
Field01 []string `msg:"field01,allownil,omitempty"`
}

// Primitive types cannot have allownil for now.
type NoAllowNil []byte
1 change: 1 addition & 0 deletions gen/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ func (d *decodeGen) gMap(m *Map) {
d.p.declare(m.Validx, m.Value.TypeName())
d.assignAndCheck(m.Keyidx, stringTyp)
d.ctx.PushVar(m.Keyidx)
m.Value.SetIsAllowNil(false)
next(d, m.Value)
d.p.mapAssign(m)
d.ctx.Pop()
Expand Down
4 changes: 4 additions & 0 deletions gen/elem.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ func (c *common) Varname() string { return c.vname }
func (c *common) Alias(typ string) { c.alias = typ }
func (c *common) hidden() {}
func (c *common) AllowNil() bool { return false }
func (c *common) SetIsAllowNil(bool) {}
func (c *common) AlwaysPtr(set *bool) bool {
if c != nil && set != nil {
c.ptrRcv = *set
Expand Down Expand Up @@ -202,6 +203,9 @@ type Elem interface {
// This is true for slices and maps.
AllowNil() bool

// SetIsAllowNil will set the allownil value, if the type supports it.
SetIsAllowNil(bool)

// AlwaysPtr will return true if receiver should always be a pointer.
AlwaysPtr(set *bool) bool

Expand Down
1 change: 1 addition & 0 deletions gen/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ func (e *encodeGen) gMap(m *Map) {
e.p.printf("\nfor %s, %s := range %s {", m.Keyidx, m.Validx, vname)
e.writeAndCheck(stringTyp, literalFmt, m.Keyidx)
e.ctx.PushVar(m.Keyidx)
m.Value.SetIsAllowNil(false)
next(e, m.Value)
e.ctx.Pop()
e.p.closeblock()
Expand Down
1 change: 1 addition & 0 deletions gen/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ func (m *marshalGen) gMap(s *Map) {
m.p.printf("\nfor %s, %s := range %s {", s.Keyidx, s.Validx, vname)
m.rawAppend(stringTyp, literalFmt, s.Keyidx)
m.ctx.PushVar(s.Keyidx)
s.Value.SetIsAllowNil(false)
next(m, s.Value)
m.ctx.Pop()
m.p.closeblock()
Expand Down
8 changes: 2 additions & 6 deletions gen/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ func (p *Printer) ApplyDirective(pass Method, t TransformPass) {

// Print prints an Elem.
func (p *Printer) Print(e Elem) error {
e.SetIsAllowNil(false)
for _, g := range p.gens {
// Elem.SetVarname() is called before the Print() step in parse.FileSet.PrintTo().
// Elem.SetVarname() generates identifiers as it walks the Elem. This can cause
Expand Down Expand Up @@ -387,12 +388,7 @@ func (p *printer) rangeBlock(ctx *Context, idx string, iter string, t traversal,
ctx.PushVar(idx)
// Tags on slices do not extend to the elements, so we always disable allownil on elements.
// If we want this to happen in the future, it should be a unique tag.
type an interface {
SetIsAllowNil(b bool)
}
if set, ok := inner.(an); ok {
set.SetIsAllowNil(false)
}
inner.SetIsAllowNil(false)
p.printf("\n for %s := range %s {", idx, iter)
next(t, inner)
p.closeblock()
Expand Down
1 change: 1 addition & 0 deletions gen/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ func (u *unmarshalGen) gMap(m *Map) {
u.p.printf("\nvar %s string; var %s %s; %s--", m.Keyidx, m.Validx, m.Value.TypeName(), sz)
u.assignAndCheck(m.Keyidx, stringTyp)
u.ctx.PushVar(m.Keyidx)
m.Value.SetIsAllowNil(false)
next(u, m.Value)
u.ctx.Pop()
u.p.mapAssign(m)
Expand Down

0 comments on commit 4558fbf

Please sign in to comment.