Skip to content

Commit e6605a1

Browse files
committed
encoding/json: use reflect.TypeAssert
Updates golang#62121 Change-Id: Ic3c4fe84a5dacfd8270aba0d5dd59f83f0a9030f Reviewed-on: https://go-review.googlesource.com/c/go/+/701955 Reviewed-by: Mark Freeman <[email protected]> Reviewed-by: Damien Neil <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 4c20f7f commit e6605a1

File tree

6 files changed

+30
-27
lines changed

6 files changed

+30
-27
lines changed

src/encoding/json/decode.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,11 +482,11 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm
482482
v.Set(reflect.New(v.Type().Elem()))
483483
}
484484
if v.Type().NumMethod() > 0 && v.CanInterface() {
485-
if u, ok := v.Interface().(Unmarshaler); ok {
485+
if u, ok := reflect.TypeAssert[Unmarshaler](v); ok {
486486
return u, nil, reflect.Value{}
487487
}
488488
if !decodingNull {
489-
if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
489+
if u, ok := reflect.TypeAssert[encoding.TextUnmarshaler](v); ok {
490490
return nil, u, reflect.Value{}
491491
}
492492
}

src/encoding/json/encode.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
475475
e.WriteString("null")
476476
return
477477
}
478-
m, ok := v.Interface().(Marshaler)
478+
m, ok := reflect.TypeAssert[Marshaler](v)
479479
if !ok {
480480
e.WriteString("null")
481481
return
@@ -498,7 +498,7 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
498498
e.WriteString("null")
499499
return
500500
}
501-
m := va.Interface().(Marshaler)
501+
m, _ := reflect.TypeAssert[Marshaler](va)
502502
b, err := m.MarshalJSON()
503503
if err == nil {
504504
e.Grow(len(b))
@@ -516,7 +516,7 @@ func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
516516
e.WriteString("null")
517517
return
518518
}
519-
m, ok := v.Interface().(encoding.TextMarshaler)
519+
m, ok := reflect.TypeAssert[encoding.TextMarshaler](v)
520520
if !ok {
521521
e.WriteString("null")
522522
return
@@ -534,7 +534,7 @@ func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
534534
e.WriteString("null")
535535
return
536536
}
537-
m := va.Interface().(encoding.TextMarshaler)
537+
m, _ := reflect.TypeAssert[encoding.TextMarshaler](va)
538538
b, err := m.MarshalText()
539539
if err != nil {
540540
e.error(&MarshalerError{v.Type(), err, "MarshalText"})
@@ -991,7 +991,7 @@ func resolveKeyName(k reflect.Value) (string, error) {
991991
if k.Kind() == reflect.String {
992992
return k.String(), nil
993993
}
994-
if tm, ok := k.Interface().(encoding.TextMarshaler); ok {
994+
if tm, ok := reflect.TypeAssert[encoding.TextMarshaler](k); ok {
995995
if k.Kind() == reflect.Pointer && k.IsNil() {
996996
return "", nil
997997
}

src/encoding/json/v2/arshal_funcs.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers {
177177
typFnc := typedMarshaler{
178178
typ: t,
179179
fnc: func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error {
180-
val, err := fn(va.castTo(t).Interface().(T))
180+
v, _ := reflect.TypeAssert[T](va.castTo(t))
181+
val, err := fn(v)
181182
if err != nil {
182183
err = wrapSkipFunc(err, "marshal function of type func(T) ([]byte, error)")
183184
if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
@@ -222,7 +223,8 @@ func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers {
222223
xe := export.Encoder(enc)
223224
prevDepth, prevLength := xe.Tokens.DepthLength()
224225
xe.Flags.Set(jsonflags.WithinArshalCall | 1)
225-
err := fn(enc, va.castTo(t).Interface().(T))
226+
v, _ := reflect.TypeAssert[T](va.castTo(t))
227+
err := fn(enc, v)
226228
xe.Flags.Set(jsonflags.WithinArshalCall | 0)
227229
currDepth, currLength := xe.Tokens.DepthLength()
228230
if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) {
@@ -269,7 +271,8 @@ func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers {
269271
if err != nil {
270272
return err // must be a syntactic or I/O error
271273
}
272-
err = fn(val, va.castTo(t).Interface().(T))
274+
v, _ := reflect.TypeAssert[T](va.castTo(t))
275+
err = fn(val, v)
273276
if err != nil {
274277
err = wrapSkipFunc(err, "unmarshal function of type func([]byte, T) error")
275278
if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
@@ -304,7 +307,8 @@ func UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers
304307
xd := export.Decoder(dec)
305308
prevDepth, prevLength := xd.Tokens.DepthLength()
306309
xd.Flags.Set(jsonflags.WithinArshalCall | 1)
307-
err := fn(dec, va.castTo(t).Interface().(T))
310+
v, _ := reflect.TypeAssert[T](va.castTo(t))
311+
err := fn(dec, v)
308312
xd.Flags.Set(jsonflags.WithinArshalCall | 0)
309313
currDepth, currLength := xd.Tokens.DepthLength()
310314
if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) {

src/encoding/json/v2/arshal_inlined.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *j
5050
}
5151

5252
if v.Type() == jsontextValueType {
53-
// TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo.
54-
b := *v.Addr().Interface().(*jsontext.Value)
53+
b, _ := reflect.TypeAssert[jsontext.Value](v.Value)
5554
if len(b) == 0 { // TODO: Should this be nil? What if it were all whitespace?
5655
return nil
5756
}
@@ -174,7 +173,7 @@ func unmarshalInlinedFallbackNext(dec *jsontext.Decoder, va addressableValue, uo
174173
v = v.indirect(true)
175174

176175
if v.Type() == jsontextValueType {
177-
b := v.Addr().Interface().(*jsontext.Value)
176+
b, _ := reflect.TypeAssert[*jsontext.Value](v.Addr())
178177
if len(*b) == 0 { // TODO: Should this be nil? What if it were all whitespace?
179178
*b = append(*b, '{')
180179
} else {

src/encoding/json/v2/arshal_methods.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler {
111111
(needAddr && va.forcedAddr) {
112112
return prevMarshal(enc, va, mo)
113113
}
114-
marshaler := va.Addr().Interface().(encoding.TextMarshaler)
114+
marshaler, _ := reflect.TypeAssert[encoding.TextMarshaler](va.Addr())
115115
if err := export.Encoder(enc).AppendRaw('"', false, func(b []byte) ([]byte, error) {
116116
b2, err := marshaler.MarshalText()
117117
return append(b, b2...), err
@@ -137,7 +137,7 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler {
137137
(needAddr && va.forcedAddr) {
138138
return prevMarshal(enc, va, mo)
139139
}
140-
appender := va.Addr().Interface().(encoding.TextAppender)
140+
appender, _ := reflect.TypeAssert[encoding.TextAppender](va.Addr())
141141
if err := export.Encoder(enc).AppendRaw('"', false, appender.AppendText); err != nil {
142142
err = wrapSkipFunc(err, "append method")
143143
if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
@@ -160,7 +160,7 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler {
160160
((needAddr && va.forcedAddr) || export.Encoder(enc).Tokens.Last.NeedObjectName()) {
161161
return prevMarshal(enc, va, mo)
162162
}
163-
marshaler := va.Addr().Interface().(Marshaler)
163+
marshaler, _ := reflect.TypeAssert[Marshaler](va.Addr())
164164
val, err := marshaler.MarshalJSON()
165165
if err != nil {
166166
err = wrapSkipFunc(err, "marshal method")
@@ -194,7 +194,8 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler {
194194
xe := export.Encoder(enc)
195195
prevDepth, prevLength := xe.Tokens.DepthLength()
196196
xe.Flags.Set(jsonflags.WithinArshalCall | 1)
197-
err := va.Addr().Interface().(MarshalerTo).MarshalJSONTo(enc)
197+
marshaler, _ := reflect.TypeAssert[MarshalerTo](va.Addr())
198+
err := marshaler.MarshalJSONTo(enc)
198199
xe.Flags.Set(jsonflags.WithinArshalCall | 0)
199200
currDepth, currLength := xe.Tokens.DepthLength()
200201
if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil {
@@ -233,7 +234,7 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler {
233234
return newUnmarshalErrorAfter(dec, t, errNonStringValue)
234235
}
235236
s := jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
236-
unmarshaler := va.Addr().Interface().(encoding.TextUnmarshaler)
237+
unmarshaler, _ := reflect.TypeAssert[encoding.TextUnmarshaler](va.Addr())
237238
if err := unmarshaler.UnmarshalText(s); err != nil {
238239
err = wrapSkipFunc(err, "unmarshal method")
239240
if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
@@ -260,7 +261,7 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler {
260261
if err != nil {
261262
return err // must be a syntactic or I/O error
262263
}
263-
unmarshaler := va.Addr().Interface().(Unmarshaler)
264+
unmarshaler, _ := reflect.TypeAssert[Unmarshaler](va.Addr())
264265
if err := unmarshaler.UnmarshalJSON(val); err != nil {
265266
err = wrapSkipFunc(err, "unmarshal method")
266267
if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
@@ -284,7 +285,8 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler {
284285
xd := export.Decoder(dec)
285286
prevDepth, prevLength := xd.Tokens.DepthLength()
286287
xd.Flags.Set(jsonflags.WithinArshalCall | 1)
287-
err := va.Addr().Interface().(UnmarshalerFrom).UnmarshalJSONFrom(dec)
288+
unmarshaler, _ := reflect.TypeAssert[UnmarshalerFrom](va.Addr())
289+
err := unmarshaler.UnmarshalJSONFrom(dec)
288290
xd.Flags.Set(jsonflags.WithinArshalCall | 0)
289291
currDepth, currLength := xd.Tokens.DepthLength()
290292
if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil {

src/encoding/json/v2/arshal_time.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
5757
return newMarshalErrorBefore(enc, t, errors.New("no default representation (see https://go.dev/issue/71631); specify an explicit format"))
5858
}
5959

60-
// TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo.
61-
m.td = *va.Addr().Interface().(*time.Duration)
60+
m.td, _ = reflect.TypeAssert[time.Duration](va.Value)
6261
k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers))
6362
if err := xe.AppendRaw(k, true, m.appendMarshal); err != nil {
6463
if !isSyntacticError(err) && !export.IsIOError(err) {
@@ -85,7 +84,7 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
8584

8685
stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers)
8786
var flags jsonwire.ValueFlags
88-
td := va.Addr().Interface().(*time.Duration)
87+
td, _ := reflect.TypeAssert[*time.Duration](va.Addr())
8988
val, err := xd.ReadValue(&flags)
9089
if err != nil {
9190
return err
@@ -129,8 +128,7 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
129128
}
130129
}
131130

132-
// TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo.
133-
m.tt = *va.Addr().Interface().(*time.Time)
131+
m.tt, _ = reflect.TypeAssert[time.Time](va.Value)
134132
k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers))
135133
if err := xe.AppendRaw(k, !m.hasCustomFormat(), m.appendMarshal); err != nil {
136134
if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
@@ -156,7 +154,7 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
156154

157155
stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers)
158156
var flags jsonwire.ValueFlags
159-
tt := va.Addr().Interface().(*time.Time)
157+
tt, _ := reflect.TypeAssert[*time.Time](va.Addr())
160158
val, err := xd.ReadValue(&flags)
161159
if err != nil {
162160
return err

0 commit comments

Comments
 (0)