@@ -132,11 +132,21 @@ func ptrEncoderFunc(typ reflect.Type) encoderFunc {
132132 }
133133}
134134
135- func encodeCustomValuePtr (e * Encoder , v reflect.Value ) error {
136- if ! v .CanAddr () {
137- return fmt .Errorf ("msgpack: Encode(non-addressable %T)" , v .Interface ())
135+ // ensureAddr returns v.Addr() if v is addressable, otherwise it allocates
136+ // a new value, copies v into it, and returns the pointer. This allows
137+ // types with pointer receivers to encode even when the source is not
138+ // addressable (e.g. map values, bare literals).
139+ func ensureAddr (v reflect.Value ) reflect.Value {
140+ if v .CanAddr () {
141+ return v .Addr ()
138142 }
139- encoder := v .Addr ().Interface ().(CustomEncoder )
143+ ptr := reflect .New (v .Type ())
144+ ptr .Elem ().Set (v )
145+ return ptr
146+ }
147+
148+ func encodeCustomValuePtr (e * Encoder , v reflect.Value ) error {
149+ encoder := ensureAddr (v ).Interface ().(CustomEncoder )
140150 return encoder .EncodeMsgpack (e )
141151}
142152
@@ -150,10 +160,7 @@ func encodeCustomValue(e *Encoder, v reflect.Value) error {
150160}
151161
152162func marshalValuePtr (e * Encoder , v reflect.Value ) error {
153- if ! v .CanAddr () {
154- return fmt .Errorf ("msgpack: Encode(non-addressable %T)" , v .Interface ())
155- }
156- return marshalValue (e , v .Addr ())
163+ return marshalValue (e , ensureAddr (v ))
157164}
158165
159166func marshalValue (e * Encoder , v reflect.Value ) error {
@@ -210,10 +217,7 @@ func nilableType(t reflect.Type) bool {
210217//------------------------------------------------------------------------------
211218
212219func marshalBinaryValueAddr (e * Encoder , v reflect.Value ) error {
213- if ! v .CanAddr () {
214- return fmt .Errorf ("msgpack: Encode(non-addressable %T)" , v .Interface ())
215- }
216- return marshalBinaryValue (e , v .Addr ())
220+ return marshalBinaryValue (e , ensureAddr (v ))
217221}
218222
219223func marshalBinaryValue (e * Encoder , v reflect.Value ) error {
@@ -233,10 +237,7 @@ func marshalBinaryValue(e *Encoder, v reflect.Value) error {
233237//------------------------------------------------------------------------------
234238
235239func marshalTextValueAddr (e * Encoder , v reflect.Value ) error {
236- if ! v .CanAddr () {
237- return fmt .Errorf ("msgpack: Encode(non-addressable %T)" , v .Interface ())
238- }
239- return marshalTextValue (e , v .Addr ())
240+ return marshalTextValue (e , ensureAddr (v ))
240241}
241242
242243func marshalTextValue (e * Encoder , v reflect.Value ) error {
0 commit comments