Marshaler interfaces not checked against addressable non-pointers
exodustx0 opened this issue · comments
Consider the following:
import "github.com/goccy/go-yaml"
type foo string
func (f *foo) MarshalYAML() ([]byte, error) {
println("BytesMarshaler hit")
return []byte(string(*f) + "quux"), nil
}
func main() {
f := foo("foobar")
in := []*foo{&f}
_, err := yaml.MarshalWithOptions(&in)
if err != nil {
println(err.Error())
return
}
}
This faithfully prints BytesMarshaler hit
. However, if you change in
into []foo{f}
, it doesn't. This is because (*Encoder).canEncodeByMarshaler()
doesn't test against v.Addr()
, and foo
's MarshalYAML
method has a pointer receiver.
Though only related and not directly relevant to this issue, I'll add that there's no reason for (*Encoder).canEncodeByMarshaler()
to use the expensive v.Interface()
, as v.Implements()
should suffice.