Skip to content

Commit 0640c11

Browse files
authored
Fix regression with inlined type with methods (#132)
In v2, we report an error if an inlined struct type also has marshal or unmarshal methods. In such a case, it is ambiguous how we are supposed to inline the type. The presence of methods indicates that the type has custom serialization behavior, but inlining seems to suggest that we should serialize the type as a Go struct. Instead of skipping the field, still add the field to the queue so that we can process the type's fields as if they were JSON serializable.
1 parent ec4fed3 commit 0640c11

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

fields.go

-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ func makeStructFields(root reflect.Type) (sf structFields, serr *SemanticError)
131131
tf := indirectType(f.typ)
132132
if implementsAny(tf, allMethodTypes...) && tf != jsontextValueType {
133133
serr = orErrorf(serr, t, "inlined Go struct field %s of type %s must not implement marshal or unmarshal methods", sf.Name, tf)
134-
continue // invalid inlined field; treat as ignored
135134
}
136135

137136
// Handle an inlined field that serializes to/from

fields_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,14 @@ func TestMakeStructFields(t *testing.T) {
261261
in: struct {
262262
A struct{ encoding.TextMarshaler } `json:",inline"`
263263
}{},
264+
want: structFields{flattened: []structField{{
265+
index: []int{0, 0},
266+
typ: reflect.TypeFor[encoding.TextMarshaler](),
267+
fieldOptions: fieldOptions{
268+
name: "TextMarshaler",
269+
quotedName: `"TextMarshaler"`,
270+
},
271+
}}},
264272
wantErr: errors.New(`inlined Go struct field A of type struct { encoding.TextMarshaler } must not implement marshal or unmarshal methods`),
265273
}, {
266274
name: jsontest.Name("InlineTextAppender"),
@@ -279,6 +287,14 @@ func TestMakeStructFields(t *testing.T) {
279287
in: struct {
280288
A struct{ MarshalerTo } `json:",inline"`
281289
}{},
290+
want: structFields{flattened: []structField{{
291+
index: []int{0, 0},
292+
typ: reflect.TypeFor[MarshalerTo](),
293+
fieldOptions: fieldOptions{
294+
name: "MarshalerTo",
295+
quotedName: `"MarshalerTo"`,
296+
},
297+
}}},
282298
wantErr: errors.New(`inlined Go struct field A of type struct { json.MarshalerTo } must not implement marshal or unmarshal methods`),
283299
}, {
284300
name: jsontest.Name("UnknownTextUnmarshaler"),
@@ -291,6 +307,14 @@ func TestMakeStructFields(t *testing.T) {
291307
in: struct {
292308
A *struct{ Unmarshaler } `json:",inline"`
293309
}{},
310+
want: structFields{flattened: []structField{{
311+
index: []int{0, 0},
312+
typ: reflect.TypeFor[Unmarshaler](),
313+
fieldOptions: fieldOptions{
314+
name: "Unmarshaler",
315+
quotedName: `"Unmarshaler"`,
316+
},
317+
}}},
294318
wantErr: errors.New(`inlined Go struct field A of type struct { json.Unmarshaler } must not implement marshal or unmarshal methods`),
295319
}, {
296320
name: jsontest.Name("UnknownJSONUnmarshalerFrom"),

0 commit comments

Comments
 (0)