Skip to content

Commit 4558fbf

Browse files
authored
Fix allownil on maps elements (#375)
* Fix allownil on maps elements * Also set for primitives. Similar to #374 map `[]byte` elements would also inherit allownil unintentionally.
1 parent 65798b6 commit 4558fbf

File tree

7 files changed

+13
-6
lines changed

7 files changed

+13
-6
lines changed

_generated/allownil.go

+3
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,6 @@ type AllowNilOmitEmpty2 struct {
228228
Field00 []string `msg:"field00,allownil,omitempty"`
229229
Field01 []string `msg:"field01,allownil,omitempty"`
230230
}
231+
232+
// Primitive types cannot have allownil for now.
233+
type NoAllowNil []byte

gen/decode.go

+1
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ func (d *decodeGen) gMap(m *Map) {
257257
d.p.declare(m.Validx, m.Value.TypeName())
258258
d.assignAndCheck(m.Keyidx, stringTyp)
259259
d.ctx.PushVar(m.Keyidx)
260+
m.Value.SetIsAllowNil(false)
260261
next(d, m.Value)
261262
d.p.mapAssign(m)
262263
d.ctx.Pop()

gen/elem.go

+4
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ func (c *common) Varname() string { return c.vname }
146146
func (c *common) Alias(typ string) { c.alias = typ }
147147
func (c *common) hidden() {}
148148
func (c *common) AllowNil() bool { return false }
149+
func (c *common) SetIsAllowNil(bool) {}
149150
func (c *common) AlwaysPtr(set *bool) bool {
150151
if c != nil && set != nil {
151152
c.ptrRcv = *set
@@ -202,6 +203,9 @@ type Elem interface {
202203
// This is true for slices and maps.
203204
AllowNil() bool
204205

206+
// SetIsAllowNil will set the allownil value, if the type supports it.
207+
SetIsAllowNil(bool)
208+
205209
// AlwaysPtr will return true if receiver should always be a pointer.
206210
AlwaysPtr(set *bool) bool
207211

gen/encode.go

+1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ func (e *encodeGen) gMap(m *Map) {
241241
e.p.printf("\nfor %s, %s := range %s {", m.Keyidx, m.Validx, vname)
242242
e.writeAndCheck(stringTyp, literalFmt, m.Keyidx)
243243
e.ctx.PushVar(m.Keyidx)
244+
m.Value.SetIsAllowNil(false)
244245
next(e, m.Value)
245246
e.ctx.Pop()
246247
e.p.closeblock()

gen/marshal.go

+1
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ func (m *marshalGen) gMap(s *Map) {
245245
m.p.printf("\nfor %s, %s := range %s {", s.Keyidx, s.Validx, vname)
246246
m.rawAppend(stringTyp, literalFmt, s.Keyidx)
247247
m.ctx.PushVar(s.Keyidx)
248+
s.Value.SetIsAllowNil(false)
248249
next(m, s.Value)
249250
m.ctx.Pop()
250251
m.p.closeblock()

gen/spec.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ func (p *Printer) ApplyDirective(pass Method, t TransformPass) {
141141

142142
// Print prints an Elem.
143143
func (p *Printer) Print(e Elem) error {
144+
e.SetIsAllowNil(false)
144145
for _, g := range p.gens {
145146
// Elem.SetVarname() is called before the Print() step in parse.FileSet.PrintTo().
146147
// Elem.SetVarname() generates identifiers as it walks the Elem. This can cause
@@ -387,12 +388,7 @@ func (p *printer) rangeBlock(ctx *Context, idx string, iter string, t traversal,
387388
ctx.PushVar(idx)
388389
// Tags on slices do not extend to the elements, so we always disable allownil on elements.
389390
// If we want this to happen in the future, it should be a unique tag.
390-
type an interface {
391-
SetIsAllowNil(b bool)
392-
}
393-
if set, ok := inner.(an); ok {
394-
set.SetIsAllowNil(false)
395-
}
391+
inner.SetIsAllowNil(false)
396392
p.printf("\n for %s := range %s {", idx, iter)
397393
next(t, inner)
398394
p.closeblock()

gen/unmarshal.go

+1
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ func (u *unmarshalGen) gMap(m *Map) {
269269
u.p.printf("\nvar %s string; var %s %s; %s--", m.Keyidx, m.Validx, m.Value.TypeName(), sz)
270270
u.assignAndCheck(m.Keyidx, stringTyp)
271271
u.ctx.PushVar(m.Keyidx)
272+
m.Value.SetIsAllowNil(false)
272273
next(u, m.Value)
273274
u.ctx.Pop()
274275
u.p.mapAssign(m)

0 commit comments

Comments
 (0)