From cbcd509324fa57b6d04b7757c4874724b76281b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Jun 2026 06:19:14 +0000 Subject: [PATCH 1/5] Initial plan From 2c43a51765e3b6a0f40d35b8dc13c56d89cecfde Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Jun 2026 06:36:15 +0000 Subject: [PATCH 2/5] Fix sortslice to match stdlib sort by package identity Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/linters/sortslice/sortslice.go | 8 +++++++- .../sortslice/testdata/src/sortslice/alias_import.go | 11 +++++++++++ .../testdata/src/sortslice/shadowed_identifier.go | 12 ++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 pkg/linters/sortslice/testdata/src/sortslice/alias_import.go create mode 100644 pkg/linters/sortslice/testdata/src/sortslice/shadowed_identifier.go diff --git a/pkg/linters/sortslice/sortslice.go b/pkg/linters/sortslice/sortslice.go index 02752e48a6f..2c81c9c09d1 100644 --- a/pkg/linters/sortslice/sortslice.go +++ b/pkg/linters/sortslice/sortslice.go @@ -6,6 +6,7 @@ package sortslice import ( "fmt" "go/ast" + "go/types" "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis/passes/inspect" @@ -52,7 +53,12 @@ func run(pass *analysis.Pass) (any, error) { return } pkgIdent, ok := sel.X.(*ast.Ident) - if !ok || pkgIdent.Name != "sort" { + if !ok { + return + } + obj := pass.TypesInfo.ObjectOf(pkgIdent) + pkgName, ok := obj.(*types.PkgName) + if !ok || pkgName.Imported().Path() != "sort" { return } diff --git a/pkg/linters/sortslice/testdata/src/sortslice/alias_import.go b/pkg/linters/sortslice/testdata/src/sortslice/alias_import.go new file mode 100644 index 00000000000..2045f59e9ed --- /dev/null +++ b/pkg/linters/sortslice/testdata/src/sortslice/alias_import.go @@ -0,0 +1,11 @@ +package sortslice + +import s "sort" + +func BadSliceAliasedImport(items []string) { + s.Slice(items, func(i, j int) bool { return items[i] < items[j] }) // want `sort\.Slice is not type-safe` +} + +func BadSliceStableAliasedImport(items []string) { + s.SliceStable(items, func(i, j int) bool { return items[i] < items[j] }) // want `sort\.SliceStable is not type-safe` +} diff --git a/pkg/linters/sortslice/testdata/src/sortslice/shadowed_identifier.go b/pkg/linters/sortslice/testdata/src/sortslice/shadowed_identifier.go new file mode 100644 index 00000000000..df46bc48ddc --- /dev/null +++ b/pkg/linters/sortslice/testdata/src/sortslice/shadowed_identifier.go @@ -0,0 +1,12 @@ +package sortslice + +type customSort struct{} + +func (customSort) Slice(_ []string, _ func(i, j int) bool) {} +func (customSort) SliceStable(_ []string, _ func(i, j int) bool) {} + +func GoodShadowedSortIdentifier(items []string) { + sort := customSort{} + sort.Slice(items, func(i, j int) bool { return items[i] < items[j] }) + sort.SliceStable(items, func(i, j int) bool { return items[i] < items[j] }) +} From 135db567d0314f5b736f07e0718ee59126a56d3a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Jun 2026 06:36:51 +0000 Subject: [PATCH 3/5] Guard sortslice package-object lookup against nil types info Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/linters/sortslice/sortslice.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/linters/sortslice/sortslice.go b/pkg/linters/sortslice/sortslice.go index 2c81c9c09d1..3df229a8df8 100644 --- a/pkg/linters/sortslice/sortslice.go +++ b/pkg/linters/sortslice/sortslice.go @@ -57,6 +57,9 @@ func run(pass *analysis.Pass) (any, error) { return } obj := pass.TypesInfo.ObjectOf(pkgIdent) + if obj == nil { + return + } pkgName, ok := obj.(*types.PkgName) if !ok || pkgName.Imported().Path() != "sort" { return From 669902fb6c21428704c811160124df9d2903e449 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Jun 2026 06:37:38 +0000 Subject: [PATCH 4/5] Document nil types-info guard in sortslice analyzer Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/linters/sortslice/sortslice.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/linters/sortslice/sortslice.go b/pkg/linters/sortslice/sortslice.go index 3df229a8df8..a417830fb19 100644 --- a/pkg/linters/sortslice/sortslice.go +++ b/pkg/linters/sortslice/sortslice.go @@ -57,6 +57,7 @@ func run(pass *analysis.Pass) (any, error) { return } obj := pass.TypesInfo.ObjectOf(pkgIdent) + // ObjectOf can be nil when type information is incomplete. if obj == nil { return } From 43099fe1ae1063a1229728df630b09e723ae4673 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Jun 2026 12:16:44 +0000 Subject: [PATCH 5/5] Add TypesInfo nil guard in sortslice analyzer Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/linters/sortslice/sortslice.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/linters/sortslice/sortslice.go b/pkg/linters/sortslice/sortslice.go index a417830fb19..7579f0d9480 100644 --- a/pkg/linters/sortslice/sortslice.go +++ b/pkg/linters/sortslice/sortslice.go @@ -56,6 +56,9 @@ func run(pass *analysis.Pass) (any, error) { if !ok { return } + if pass.TypesInfo == nil { + return + } obj := pass.TypesInfo.ObjectOf(pkgIdent) // ObjectOf can be nil when type information is incomplete. if obj == nil { @@ -68,6 +71,7 @@ func run(pass *analysis.Pass) (any, error) { switch sel.Sel.Name { case "Slice": + // Keep diagnostics on canonical stdlib names even for aliased imports. pass.ReportRangef(call, "sort.Slice is not type-safe; use slices.SortFunc instead") case "SliceStable": pass.ReportRangef(call, "sort.SliceStable is not type-safe; use slices.SortStableFunc instead")