Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Steup Go
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: "1.24"
Expand Down
7 changes: 7 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: "2"
linters:
exclusions:
rules:
# Tests copied from the stdlib are not meant to be linted.
- path: 'golang_(.+_)?test\.go'
source: "^" # regex
2 changes: 1 addition & 1 deletion benchmarks/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ benchstat := ${GOPATH}/bin/benchstat
all:

$(benchstat):
go install golang.org/x/perf/cmd/benchstat
go install golang.org/x/perf/cmd/benchstat@latest

$(benchmark.cmd.dir)/message.pb.go: $(benchmark.cmd.dir)/message.proto
@protoc -I. \
Expand Down
21 changes: 9 additions & 12 deletions json/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding"
"encoding/json"
"fmt"
"maps"
"math/big"
"reflect"
"sort"
Expand Down Expand Up @@ -73,12 +74,9 @@ func cacheLoad() map[unsafe.Pointer]codec {

func cacheStore(typ reflect.Type, cod codec, oldCodecs map[unsafe.Pointer]codec) {
newCodecs := make(map[unsafe.Pointer]codec, len(oldCodecs)+1)
maps.Copy(newCodecs, oldCodecs)
Copy link

Copilot AI Jul 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using maps.Copy is more efficient than manually iterating over the map entries

Copilot uses AI. Check for mistakes.
newCodecs[typeid(typ)] = cod

for t, c := range oldCodecs {
newCodecs[t] = c
}

cache.Store(&newCodecs)
}

Expand Down Expand Up @@ -205,7 +203,7 @@ func constructCodec(t reflect.Type, seen map[reflect.Type]*structType, canAddr b
c = constructUnsupportedTypeCodec(t)
}

p := reflect.PtrTo(t)
p := reflect.PointerTo(t)

if canAddr {
switch {
Expand Down Expand Up @@ -291,7 +289,7 @@ func constructSliceCodec(t reflect.Type, seen map[reflect.Type]*structType) code
// Go 1.7+ behavior: slices of byte types (and aliases) may override the
// default encoding and decoding behaviors by implementing marshaler and
// unmarshaler interfaces.
p := reflect.PtrTo(e)
p := reflect.PointerTo(e)
c := codec{}

switch {
Expand Down Expand Up @@ -391,7 +389,7 @@ func constructMapCodec(t reflect.Type, seen map[reflect.Type]*structType) codec
kc := codec{}
vc := constructCodec(v, seen, false)

if k.Implements(textMarshalerType) || reflect.PtrTo(k).Implements(textUnmarshalerType) {
if k.Implements(textMarshalerType) || reflect.PointerTo(k).Implements(textUnmarshalerType) {
kc.encode = constructTextMarshalerEncodeFunc(k, false)
kc.decode = constructTextUnmarshalerDecodeFunc(k, true)

Expand Down Expand Up @@ -972,7 +970,6 @@ type structType struct {
ficaseIndex map[string]*structField
keyset []byte
typ reflect.Type
inlined bool
}

type structField struct {
Expand Down Expand Up @@ -1095,10 +1092,10 @@ var (
timeType = reflect.TypeOf(time.Time{})
rawMessageType = reflect.TypeOf(RawMessage(nil))

numberPtrType = reflect.PtrTo(numberType)
durationPtrType = reflect.PtrTo(durationType)
timePtrType = reflect.PtrTo(timeType)
rawMessagePtrType = reflect.PtrTo(rawMessageType)
numberPtrType = reflect.PointerTo(numberType)
durationPtrType = reflect.PointerTo(durationType)
timePtrType = reflect.PointerTo(timeType)
rawMessagePtrType = reflect.PointerTo(rawMessageType)

sliceInterfaceType = reflect.TypeOf(([]any)(nil))
sliceStringType = reflect.TypeOf(([]any)(nil))
Expand Down
4 changes: 2 additions & 2 deletions json/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -1410,7 +1410,7 @@ func (d decoder) decodeMaybeEmptyInterface(b []byte, p unsafe.Pointer, t reflect
return d.decodeUnmarshalTypeError(b, p, t)
}

func (d decoder) decodeUnmarshalTypeError(b []byte, p unsafe.Pointer, t reflect.Type) ([]byte, error) {
func (d decoder) decodeUnmarshalTypeError(b []byte, _ unsafe.Pointer, t reflect.Type) ([]byte, error) {
v, b, _, err := d.parseValue(b)
if err != nil {
return b, err
Expand Down Expand Up @@ -1500,7 +1500,7 @@ func (d decoder) decodeTextUnmarshaler(b []byte, p unsafe.Pointer, t reflect.Typ
value = "array"
}

return b, &UnmarshalTypeError{Value: value, Type: reflect.PtrTo(t)}
return b, &UnmarshalTypeError{Value: value, Type: reflect.PointerTo(t)}
}

func (d decoder) prependField(key, field string) string {
Expand Down
4 changes: 2 additions & 2 deletions json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
type Delim = json.Delim

// InvalidUTF8Error is documented at https://golang.org/pkg/encoding/json/#InvalidUTF8Error
type InvalidUTF8Error = json.InvalidUTF8Error
type InvalidUTF8Error = json.InvalidUTF8Error //nolint:staticcheck // compat.

// InvalidUnmarshalError is documented at https://golang.org/pkg/encoding/json/#InvalidUnmarshalError
type InvalidUnmarshalError = json.InvalidUnmarshalError
Expand All @@ -39,7 +39,7 @@ type SyntaxError = json.SyntaxError
type Token = json.Token

// UnmarshalFieldError is documented at https://golang.org/pkg/encoding/json/#UnmarshalFieldError
type UnmarshalFieldError = json.UnmarshalFieldError
type UnmarshalFieldError = json.UnmarshalFieldError //nolint:staticcheck // compat.

// UnmarshalTypeError is documented at https://golang.org/pkg/encoding/json/#UnmarshalTypeError
type UnmarshalTypeError = json.UnmarshalTypeError
Expand Down
11 changes: 3 additions & 8 deletions json/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ var testValues = [...]any{
A string `json:"name"`
B string `json:"-"`
C string `json:",omitempty"`
D map[string]any `json:",string"`
D map[string]any `json:",string"` //nolint:staticcheck // intentional
e string
}{A: "Luke", D: map[string]any{"answer": float64(42)}},
struct{ point }{point{1, 2}},
Expand Down Expand Up @@ -880,12 +880,11 @@ func TestDecodeLines(t *testing.T) {
t.Run(test.desc, func(t *testing.T) {
d := NewDecoder(test.reader)
var count int
var err error
for {
var o obj
err = d.Decode(&o)
err := d.Decode(&o)
Copy link

Copilot AI Jul 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable scoping improved by declaring err within the loop scope where it's used

Copilot uses AI. Check for mistakes.
if err != nil {
if err == io.EOF {
if errors.Is(err, io.EOF) {
Copy link

Copilot AI Jul 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using errors.Is() is the recommended way to check for specific errors instead of direct equality comparison

Copilot uses AI. Check for mistakes.
break
}

Expand All @@ -904,10 +903,6 @@ func TestDecodeLines(t *testing.T) {
count++
}

if err != nil && err != io.EOF {
t.Error(err)
}

if count != test.expectCount {
t.Errorf("expected %d objects, got %d", test.expectCount, count)
}
Expand Down
5 changes: 0 additions & 5 deletions json/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ const (
cr = '\r'
)

const (
escape = '\\'
quote = '"'
)

func internalParseFlags(b []byte) (flags ParseFlags) {
// Don't consider surrounding whitespace
b = skipSpaces(b)
Expand Down