From 355151893a75e2f340cb1cc534265318c0a12e39 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Thu, 29 May 2025 18:43:16 -0400 Subject: [PATCH 1/5] Align BSON interface slice decoding with json package. --- bson/default_value_decoders.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bson/default_value_decoders.go b/bson/default_value_decoders.go index 42ea2e5864..56764794ac 100644 --- a/bson/default_value_decoders.go +++ b/bson/default_value_decoders.go @@ -1351,7 +1351,7 @@ func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]refle } var elem reflect.Value - if vDecoder == nil { + if vDecoder == nil && idx < val.Len() { elem = val.Index(idx).Elem() switch { case elem.Kind() != reflect.Ptr || elem.IsNil(): @@ -1359,6 +1359,9 @@ func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]refle if err != nil { return nil, err } + if !elem.CanSet() { + elem = reflect.New(elem.Type()).Elem() + } err = valueDecoder.DecodeValue(dc, vr, elem) if err != nil { return nil, newDecodeError(strconv.Itoa(idx), err) @@ -1380,6 +1383,12 @@ func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]refle } } } else { + if vDecoder == nil { + vDecoder, err = dc.LookupDecoder(eType) + if err != nil { + return nil, err + } + } elem, err = decodeTypeOrValueWithInfo(vDecoder, dc, vr, eType) if err != nil { return nil, newDecodeError(strconv.Itoa(idx), err) From 841cd9674497dd26045cfa8eeee09596b8df7820 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Tue, 3 Jun 2025 17:03:11 -0400 Subject: [PATCH 2/5] add tests --- bson/bsoncodec.go | 3 +++ bson/decoder_test.go | 23 +++++++++++++++++++++++ bson/unmarshal_test.go | 22 ++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/bson/bsoncodec.go b/bson/bsoncodec.go index 80e13e7d81..91592a3e63 100644 --- a/bson/bsoncodec.go +++ b/bson/bsoncodec.go @@ -69,6 +69,9 @@ func (vde ValueDecoderError) Error() string { if vde.Received.IsValid() { received = vde.Received.Type().String() } + if !vde.Received.CanSet() { + received = "unsettable " + received + } return fmt.Sprintf("%s can only decode valid and settable %s, but got %s", vde.Name, strings.Join(typeKinds, ", "), received) } diff --git a/bson/decoder_test.go b/bson/decoder_test.go index e88aca6d6b..6fd037a49d 100644 --- a/bson/decoder_test.go +++ b/bson/decoder_test.go @@ -172,6 +172,29 @@ func TestDecodingInterfaces(t *testing.T) { assert.Equal(t, testStruct{[3]interface{}{&str, &i, nil}}, receiver) } + return data, &receiver, check + }, + }, + { + name: "struct with interface slice containing concrete values", + stub: func() ([]byte, interface{}, func(*testing.T)) { + type testStruct struct { + Values []interface{} + } + + data := docToBytes(struct { + Values []interface{} + }{ + Values: []interface{}{1, 2, 3}, + }) + + receiver := testStruct{[]interface{}{7, 8}} + + check := func(t *testing.T) { + t.Helper() + assert.Equal(t, testStruct{[]interface{}{1, 2, int32(3)}}, receiver) + } + return data, &receiver, check }, }, diff --git a/bson/unmarshal_test.go b/bson/unmarshal_test.go index 35a66141be..e6280c6d99 100644 --- a/bson/unmarshal_test.go +++ b/bson/unmarshal_test.go @@ -422,6 +422,28 @@ func TestUnmarshalInterface(t *testing.T) { assert.Equal(t, testStruct{[3]interface{}{&str, &i, nil}}, receiver) } + return data, &receiver, check + }, + }, + { + name: "struct with interface slice containing concrete values", + stub: func() ([]byte, interface{}, func(*testing.T)) { + type testStruct struct { + Values []interface{} + } + data := docToBytes(struct { + Values []interface{} + }{ + Values: []interface{}{1, 2, 3}, + }) + + receiver := testStruct{[]interface{}{7, 8}} + + check := func(t *testing.T) { + t.Helper() + assert.Equal(t, testStruct{[]interface{}{1, 2, int32(3)}}, receiver) + } + return data, &receiver, check }, }, From 779d6b0cab0973985d6321ec8c28fa945be00392 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Tue, 3 Jun 2025 19:40:28 -0400 Subject: [PATCH 3/5] fix tests --- bson/default_value_decoders_test.go | 144 ++++++++++++++++++++++------ bson/primitive_codecs_test.go | 10 +- 2 files changed, 123 insertions(+), 31 deletions(-) diff --git a/bson/default_value_decoders_test.go b/bson/default_value_decoders_test.go index 4dad538a26..b0e68b8f76 100644 --- a/bson/default_value_decoders_test.go +++ b/bson/default_value_decoders_test.go @@ -75,7 +75,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeBoolean}, nothing, - ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "BooleanDecodeValue", + Kinds: []reflect.Kind{reflect.Bool}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not boolean", @@ -741,7 +745,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeDateTime, Return: int64(0)}, nothing, - ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "TimeDecodeValue", + Types: []reflect.Type{tTime}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "ReadDateTime error", @@ -795,7 +803,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{}, nothing, - ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "MapDecodeValue", + Kinds: []reflect.Kind{reflect.Map}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "wrong kind (non-string key)", @@ -873,7 +885,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{}, nothing, - ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "ArrayDecodeValue", + Kinds: []reflect.Kind{reflect.Array}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "can set false", @@ -967,7 +983,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{}, nothing, - ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "SliceDecodeValue", + Kinds: []reflect.Kind{reflect.Slice}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "can set false", @@ -1061,7 +1081,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeObjectID}, nothing, - ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "ObjectIDDecodeValue", + Types: []reflect.Type{tOID}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not objectID", @@ -1148,7 +1172,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeDecimal128}, nothing, - ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "Decimal128DecodeValue", + Types: []reflect.Type{tDecimal}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not decimal128", @@ -1210,7 +1238,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeObjectID}, nothing, - ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "JSONNumberDecodeValue", + Types: []reflect.Type{tJSONNumber}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not double/int32/int64", @@ -1312,7 +1344,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeString, Return: "http://example.com"}, nothing, - ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: reflect.ValueOf(int64(0))}, + ValueDecoderError{ + Name: "URLDecodeValue", + Types: []reflect.Type{tURL}, + Received: reflect.New(reflect.TypeOf(int64(0))).Elem(), + }, }, { "ReadString error", @@ -1386,7 +1422,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeBinary, Return: bsoncore.Value{Type: bsoncore.TypeBinary}}, nothing, - ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: reflect.ValueOf(int64(0))}, + ValueDecoderError{ + Name: "ByteSliceDecodeValue", + Types: []reflect.Type{tByteSlice}, + Received: reflect.New(reflect.TypeOf(int64(0))).Elem(), + }, }, { "ReadBinary error", @@ -1479,7 +1519,7 @@ func TestDefaultValueDecoders(t *testing.T) { ValueDecoderError{ Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, - Received: reflect.ValueOf(wrong), + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), }, }, { @@ -1510,7 +1550,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, nil, nothing, - ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "UnmarshalerDecodeValue", + Types: []reflect.Type{tUnmarshaler}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "copy error", @@ -1589,7 +1633,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{}, nothing, - ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tBinary}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "BinaryDecodeValue", + Types: []reflect.Type{tBinary}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not binary", @@ -1649,7 +1697,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeUndefined}, nothing, - ValueDecoderError{Name: "UndefinedDecodeValue", Types: []reflect.Type{tUndefined}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "UndefinedDecodeValue", + Types: []reflect.Type{tUndefined}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not undefined", @@ -1695,7 +1747,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeDateTime}, nothing, - ValueDecoderError{Name: "DateTimeDecodeValue", Types: []reflect.Type{tDateTime}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "DateTimeDecodeValue", + Types: []reflect.Type{tDateTime}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not datetime", @@ -1749,7 +1805,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeNull}, nothing, - ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "NullDecodeValue", + Types: []reflect.Type{tNull}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not null", @@ -1787,7 +1847,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeRegex}, nothing, - ValueDecoderError{Name: "RegexDecodeValue", Types: []reflect.Type{tRegex}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "RegexDecodeValue", + Types: []reflect.Type{tRegex}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not regex", @@ -1847,7 +1911,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeDBPointer}, nothing, - ValueDecoderError{Name: "DBPointerDecodeValue", Types: []reflect.Type{tDBPointer}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "DBPointerDecodeValue", + Types: []reflect.Type{tDBPointer}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not dbpointer", @@ -1912,7 +1980,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeTimestamp}, nothing, - ValueDecoderError{Name: "TimestampDecodeValue", Types: []reflect.Type{tTimestamp}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "TimestampDecodeValue", + Types: []reflect.Type{tTimestamp}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not timestamp", @@ -1972,7 +2044,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeMinKey}, nothing, - ValueDecoderError{Name: "MinKeyDecodeValue", Types: []reflect.Type{tMinKey}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "MinKeyDecodeValue", + Types: []reflect.Type{tMinKey}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not null", @@ -2026,7 +2102,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeMaxKey}, nothing, - ValueDecoderError{Name: "MaxKeyDecodeValue", Types: []reflect.Type{tMaxKey}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "MaxKeyDecodeValue", + Types: []reflect.Type{tMaxKey}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not null", @@ -2080,7 +2160,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeJavaScript, Return: ""}, nothing, - ValueDecoderError{Name: "JavaScriptDecodeValue", Types: []reflect.Type{tJavaScript}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "JavaScriptDecodeValue", + Types: []reflect.Type{tJavaScript}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not Javascript", @@ -2134,7 +2218,11 @@ func TestDefaultValueDecoders(t *testing.T) { nil, &valueReaderWriter{BSONType: TypeSymbol, Return: ""}, nothing, - ValueDecoderError{Name: "SymbolDecodeValue", Types: []reflect.Type{tSymbol}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "SymbolDecodeValue", + Types: []reflect.Type{tSymbol}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "type not Symbol", @@ -2191,7 +2279,7 @@ func TestDefaultValueDecoders(t *testing.T) { ValueDecoderError{ Name: "CoreDocumentDecodeValue", Types: []reflect.Type{tCoreDocument}, - Received: reflect.ValueOf(wrong), + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), }, }, { @@ -2203,7 +2291,7 @@ func TestDefaultValueDecoders(t *testing.T) { ValueDecoderError{ Name: "CoreDocumentDecodeValue", Types: []reflect.Type{tCoreDocument}, - Received: reflect.ValueOf((*bsoncore.Document)(nil)), + Received: reflect.New(reflect.TypeOf((*bsoncore.Document)(nil))).Elem(), }, }, { @@ -2259,7 +2347,7 @@ func TestDefaultValueDecoders(t *testing.T) { ValueDecoderError{ Name: "CodeWithScopeDecodeValue", Types: []reflect.Type{tCodeWithScope}, - Received: reflect.ValueOf(wrong), + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), }, }, { @@ -2320,7 +2408,7 @@ func TestDefaultValueDecoders(t *testing.T) { ValueDecoderError{ Name: "CoreArrayDecodeValue", Types: []reflect.Type{tCoreArray}, - Received: reflect.ValueOf(wrong), + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), }, }, { @@ -2332,7 +2420,7 @@ func TestDefaultValueDecoders(t *testing.T) { ValueDecoderError{ Name: "CoreArrayDecodeValue", Types: []reflect.Type{tCoreArray}, - Received: reflect.ValueOf((*bsoncore.Array)(nil)), + Received: reflect.New(reflect.TypeOf((*bsoncore.Array)(nil))).Elem(), }, }, }, diff --git a/bson/primitive_codecs_test.go b/bson/primitive_codecs_test.go index d7480f9eaa..6071ea02f9 100644 --- a/bson/primitive_codecs_test.go +++ b/bson/primitive_codecs_test.go @@ -507,7 +507,7 @@ func TestPrimitiveValueDecoders(t *testing.T) { ValueDecoderError{ Name: "RawValueDecodeValue", Types: []reflect.Type{tRawValue}, - Received: reflect.ValueOf(wrong), + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), }, }, { @@ -548,7 +548,11 @@ func TestPrimitiveValueDecoders(t *testing.T) { nil, &valueReaderWriter{}, nothing, - ValueDecoderError{Name: "RawDecodeValue", Types: []reflect.Type{tRaw}, Received: reflect.ValueOf(wrong)}, + ValueDecoderError{ + Name: "RawDecodeValue", + Types: []reflect.Type{tRaw}, + Received: reflect.New(reflect.TypeOf(wrong)).Elem(), + }, }, { "*Raw is nil", @@ -559,7 +563,7 @@ func TestPrimitiveValueDecoders(t *testing.T) { ValueDecoderError{ Name: "RawDecodeValue", Types: []reflect.Type{tRaw}, - Received: reflect.ValueOf((*Raw)(nil)), + Received: reflect.New(reflect.TypeOf((*Raw)(nil))).Elem(), }, }, { From 0bb71be8534653907b7971b075805e069df26bdf Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Wed, 4 Jun 2025 17:15:20 -0400 Subject: [PATCH 4/5] update comments --- bson/decoder_test.go | 2 +- bson/default_value_decoders.go | 16 ++++++++++++++-- bson/unmarshal_test.go | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/bson/decoder_test.go b/bson/decoder_test.go index 6fd037a49d..4179b5e4ba 100644 --- a/bson/decoder_test.go +++ b/bson/decoder_test.go @@ -176,7 +176,7 @@ func TestDecodingInterfaces(t *testing.T) { }, }, { - name: "struct with interface slice containing concrete values", + name: "overwriting prepopulated slice", stub: func() ([]byte, interface{}, func(*testing.T)) { type testStruct struct { Values []interface{} diff --git a/bson/default_value_decoders.go b/bson/default_value_decoders.go index 56764794ac..d419e7330a 100644 --- a/bson/default_value_decoders.go +++ b/bson/default_value_decoders.go @@ -1332,8 +1332,12 @@ func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]refle eType := val.Type().Elem() + isInterfaceSlice := eType.Kind() == reflect.Interface && val.Len() > 0 + + // If this is not an interface slice with pre-populated elements, we can look up + // the decoder for eType once. var vDecoder ValueDecoder - if !(eType.Kind() == reflect.Interface && val.Len() > 0) { + if !isInterfaceSlice { vDecoder, err = dc.LookupDecoder(eType) if err != nil { return nil, err @@ -1351,7 +1355,9 @@ func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]refle } var elem reflect.Value - if vDecoder == nil && idx < val.Len() { + if isInterfaceSlice && idx < val.Len() { + // Decode into an existing interface{} slot. + elem = val.Index(idx).Elem() switch { case elem.Kind() != reflect.Ptr || elem.IsNil(): @@ -1359,9 +1365,12 @@ func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]refle if err != nil { return nil, err } + + // If an element is allocated and unsettable, it must be overwritten. if !elem.CanSet() { elem = reflect.New(elem.Type()).Elem() } + err = valueDecoder.DecodeValue(dc, vr, elem) if err != nil { return nil, newDecodeError(strconv.Itoa(idx), err) @@ -1383,6 +1392,9 @@ func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]refle } } } else { + // For non-interface slices, or if we've exhuasted the pre-populated + // slots, we create a fresh value. + if vDecoder == nil { vDecoder, err = dc.LookupDecoder(eType) if err != nil { diff --git a/bson/unmarshal_test.go b/bson/unmarshal_test.go index e6280c6d99..06dfe4ff22 100644 --- a/bson/unmarshal_test.go +++ b/bson/unmarshal_test.go @@ -426,7 +426,7 @@ func TestUnmarshalInterface(t *testing.T) { }, }, { - name: "struct with interface slice containing concrete values", + name: "overwriting prepopulated slice", stub: func() ([]byte, interface{}, func(*testing.T)) { type testStruct struct { Values []interface{} From 033957f8df1643e46dce01f513df1815447e4721 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Wed, 4 Jun 2025 17:23:52 -0400 Subject: [PATCH 5/5] fix typo --- bson/default_value_decoders.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/default_value_decoders.go b/bson/default_value_decoders.go index d419e7330a..b7d2033999 100644 --- a/bson/default_value_decoders.go +++ b/bson/default_value_decoders.go @@ -1392,7 +1392,7 @@ func decodeDefault(dc DecodeContext, vr ValueReader, val reflect.Value) ([]refle } } } else { - // For non-interface slices, or if we've exhuasted the pre-populated + // For non-interface slices, or if we've exhausted the pre-populated // slots, we create a fresh value. if vDecoder == nil {