all: change from sort functions to slices functions where feasible

Doing this because the slices functions are slightly faster and
slightly easier to use. It also removes one dependency layer.

This CL does not change packages that are used during bootstrap,
as the bootstrap compiler does not have the required slices functions.
It does not change the go/scanner package because the ErrorList
Len, Swap, and Less methods are part of the Go 1 API.

Change-Id: If52899be791c829198e11d2408727720b91ebe8a
Reviewed-on: https://go-review.googlesource.com/c/go/+/587655
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Commit-Queue: Ian Lance Taylor <iant@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
Ian Lance Taylor 2024-05-22 13:38:40 -07:00 committed by Gopher Robot
parent 1849ce6a45
commit b0b1d42db3
89 changed files with 499 additions and 454 deletions

View File

@ -10,7 +10,7 @@ import (
"io" "io"
"io/fs" "io/fs"
"path" "path"
"sort" "slices"
"strings" "strings"
"time" "time"
) )
@ -174,7 +174,7 @@ func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
for k := range paxHdrs { for k := range paxHdrs {
keys = append(keys, k) keys = append(keys, k)
} }
sort.Strings(keys) slices.Sort(keys)
// Write each record to a buffer. // Write each record to a buffer.
var buf strings.Builder var buf strings.Builder

View File

@ -13,7 +13,7 @@ import (
"os" "os"
"path" "path"
"reflect" "reflect"
"sort" "slices"
"strings" "strings"
"testing" "testing"
"testing/fstest" "testing/fstest"
@ -749,7 +749,7 @@ func TestPaxHeadersSorted(t *testing.T) {
bytes.Index(buf.Bytes(), []byte("foo=foo")), bytes.Index(buf.Bytes(), []byte("foo=foo")),
bytes.Index(buf.Bytes(), []byte("qux=qux")), bytes.Index(buf.Bytes(), []byte("qux=qux")),
} }
if !sort.IntsAreSorted(indices) { if !slices.IsSorted(indices) {
t.Fatal("PAX headers are not sorted") t.Fatal("PAX headers are not sorted")
} }
} }

View File

@ -16,7 +16,7 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"sort" "slices"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -862,14 +862,19 @@ func (r *Reader) initFileList() {
} }
} }
sort.Slice(r.fileList, func(i, j int) bool { return fileEntryLess(r.fileList[i].name, r.fileList[j].name) }) slices.SortFunc(r.fileList, func(a, b fileListEntry) int {
return fileEntryCompare(a.name, b.name)
})
}) })
} }
func fileEntryLess(x, y string) bool { func fileEntryCompare(x, y string) int {
xdir, xelem, _ := split(x) xdir, xelem, _ := split(x)
ydir, yelem, _ := split(y) ydir, yelem, _ := split(y)
return xdir < ydir || xdir == ydir && xelem < yelem if xdir != ydir {
return strings.Compare(xdir, ydir)
}
return strings.Compare(xelem, yelem)
} }
// Open opens the named file in the ZIP archive, // Open opens the named file in the ZIP archive,
@ -920,9 +925,12 @@ func (r *Reader) openLookup(name string) *fileListEntry {
dir, elem, _ := split(name) dir, elem, _ := split(name)
files := r.fileList files := r.fileList
i := sort.Search(len(files), func(i int) bool { i, _ := slices.BinarySearchFunc(files, dir, func(a fileListEntry, dir string) (ret int) {
idir, ielem, _ := split(files[i].name) idir, ielem, _ := split(a.name)
return idir > dir || idir == dir && ielem >= elem if dir != idir {
return strings.Compare(idir, dir)
}
return strings.Compare(ielem, elem)
}) })
if i < len(files) { if i < len(files) {
fname := files[i].name fname := files[i].name
@ -935,13 +943,21 @@ func (r *Reader) openLookup(name string) *fileListEntry {
func (r *Reader) openReadDir(dir string) []fileListEntry { func (r *Reader) openReadDir(dir string) []fileListEntry {
files := r.fileList files := r.fileList
i := sort.Search(len(files), func(i int) bool { i, _ := slices.BinarySearchFunc(files, dir, func(a fileListEntry, dir string) int {
idir, _, _ := split(files[i].name) idir, _, _ := split(a.name)
return idir >= dir if dir != idir {
return strings.Compare(idir, dir)
}
// find the first entry with dir
return +1
}) })
j := sort.Search(len(files), func(j int) bool { j, _ := slices.BinarySearchFunc(files, dir, func(a fileListEntry, dir string) int {
jdir, _, _ := split(files[j].name) jdir, _, _ := split(a.name)
return jdir > dir if dir != jdir {
return strings.Compare(jdir, dir)
}
// find the last entry with dir
return -1
}) })
return files[i:j] return files[i:j]
} }

View File

@ -8,13 +8,14 @@ package zip
import ( import (
"bytes" "bytes"
"cmp"
"errors" "errors"
"fmt" "fmt"
"hash" "hash"
"internal/testenv" "internal/testenv"
"io" "io"
"runtime" "runtime"
"sort" "slices"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -214,9 +215,8 @@ func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
if len(p) == 0 { if len(p) == 0 {
return return
} }
skipParts := sort.Search(len(r.buf), func(i int) bool { skipParts, _ := slices.BinarySearchFunc(r.buf, off, func(rb repeatedByte, off int64) int {
part := &r.buf[i] return cmp.Compare(rb.off+rb.n, off)
return part.off+part.n > off
}) })
parts := r.buf[skipParts:] parts := r.buf[skipParts:]
if len(parts) > 0 { if len(parts) > 0 {

View File

@ -10,7 +10,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"sort" "slices"
"strconv" "strconv"
"unicode" "unicode"
) )
@ -165,11 +165,8 @@ func ExampleCompare_search() {
// Binary search to find a matching byte slice. // Binary search to find a matching byte slice.
var needle []byte var needle []byte
var haystack [][]byte // Assume sorted var haystack [][]byte // Assume sorted
i := sort.Search(len(haystack), func(i int) bool { _, found := slices.BinarySearchFunc(haystack, needle, bytes.Compare)
// Return haystack[i] >= needle. if found {
return bytes.Compare(haystack[i], needle) >= 0
})
if i < len(haystack) && bytes.Equal(haystack[i], needle) {
// Found it! // Found it!
} }
} }

View File

@ -1078,18 +1078,18 @@ func TestGoListTest(t *testing.T) {
tg.makeTempdir() tg.makeTempdir()
tg.setenv("GOCACHE", tg.tempdir) tg.setenv("GOCACHE", tg.tempdir)
tg.run("list", "-test", "-deps", "sort") tg.run("list", "-test", "-deps", "bytes")
tg.grepStdout(`^sort.test$`, "missing test main") tg.grepStdout(`^bytes.test$`, "missing test main")
tg.grepStdout(`^sort$`, "missing real sort") tg.grepStdout(`^bytes$`, "missing real bytes")
tg.grepStdout(`^sort \[sort.test\]$`, "missing test copy of sort") tg.grepStdout(`^bytes \[bytes.test\]$`, "missing test copy of bytes")
tg.grepStdout(`^testing \[sort.test\]$`, "missing test copy of testing") tg.grepStdout(`^testing \[bytes.test\]$`, "missing test copy of testing")
tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing") tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
tg.run("list", "-test", "sort") tg.run("list", "-test", "bytes")
tg.grepStdout(`^sort.test$`, "missing test main") tg.grepStdout(`^bytes.test$`, "missing test main")
tg.grepStdout(`^sort$`, "missing real sort") tg.grepStdout(`^bytes$`, "missing real bytes")
tg.grepStdout(`^sort \[sort.test\]$`, "unexpected test copy of sort") tg.grepStdout(`^bytes \[bytes.test\]$`, "unexpected test copy of bytes")
tg.grepStdoutNot(`^testing \[sort.test\]$`, "unexpected test copy of testing") tg.grepStdoutNot(`^testing \[bytes.test\]$`, "unexpected test copy of testing")
tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing") tg.grepStdoutNot(`^testing$`, "unexpected real copy of testing")
tg.run("list", "-test", "cmd/buildid", "cmd/doc") tg.run("list", "-test", "cmd/buildid", "cmd/doc")

View File

@ -26,7 +26,6 @@ import (
"os" "os"
"reflect" "reflect"
"slices" "slices"
"sort"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -1548,61 +1547,71 @@ func TestCipherSuites(t *testing.T) {
} }
// Check that the list is sorted according to the documented criteria. // Check that the list is sorted according to the documented criteria.
isBetter := func(a, b int) bool { isBetter := func(a, b uint16) int {
aSuite, bSuite := cipherSuiteByID(prefOrder[a]), cipherSuiteByID(prefOrder[b]) aSuite, bSuite := cipherSuiteByID(a), cipherSuiteByID(b)
aName, bName := CipherSuiteName(prefOrder[a]), CipherSuiteName(prefOrder[b]) aName, bName := CipherSuiteName(a), CipherSuiteName(b)
// * < RC4 // * < RC4
if !strings.Contains(aName, "RC4") && strings.Contains(bName, "RC4") { if !strings.Contains(aName, "RC4") && strings.Contains(bName, "RC4") {
return true return -1
} else if strings.Contains(aName, "RC4") && !strings.Contains(bName, "RC4") { } else if strings.Contains(aName, "RC4") && !strings.Contains(bName, "RC4") {
return false return +1
} }
// * < CBC_SHA256 // * < CBC_SHA256
if !strings.Contains(aName, "CBC_SHA256") && strings.Contains(bName, "CBC_SHA256") { if !strings.Contains(aName, "CBC_SHA256") && strings.Contains(bName, "CBC_SHA256") {
return true return -1
} else if strings.Contains(aName, "CBC_SHA256") && !strings.Contains(bName, "CBC_SHA256") { } else if strings.Contains(aName, "CBC_SHA256") && !strings.Contains(bName, "CBC_SHA256") {
return false return +1
} }
// * < 3DES // * < 3DES
if !strings.Contains(aName, "3DES") && strings.Contains(bName, "3DES") { if !strings.Contains(aName, "3DES") && strings.Contains(bName, "3DES") {
return true return -1
} else if strings.Contains(aName, "3DES") && !strings.Contains(bName, "3DES") { } else if strings.Contains(aName, "3DES") && !strings.Contains(bName, "3DES") {
return false return +1
} }
// ECDHE < * // ECDHE < *
if aSuite.flags&suiteECDHE != 0 && bSuite.flags&suiteECDHE == 0 { if aSuite.flags&suiteECDHE != 0 && bSuite.flags&suiteECDHE == 0 {
return true return -1
} else if aSuite.flags&suiteECDHE == 0 && bSuite.flags&suiteECDHE != 0 { } else if aSuite.flags&suiteECDHE == 0 && bSuite.flags&suiteECDHE != 0 {
return false return +1
} }
// AEAD < CBC // AEAD < CBC
if aSuite.aead != nil && bSuite.aead == nil { if aSuite.aead != nil && bSuite.aead == nil {
return true return -1
} else if aSuite.aead == nil && bSuite.aead != nil { } else if aSuite.aead == nil && bSuite.aead != nil {
return false return +1
} }
// AES < ChaCha20 // AES < ChaCha20
if strings.Contains(aName, "AES") && strings.Contains(bName, "CHACHA20") { if strings.Contains(aName, "AES") && strings.Contains(bName, "CHACHA20") {
return i == 0 // true for cipherSuitesPreferenceOrder // negative for cipherSuitesPreferenceOrder
if i == 0 {
return -1
} else {
return +1
}
} else if strings.Contains(aName, "CHACHA20") && strings.Contains(bName, "AES") { } else if strings.Contains(aName, "CHACHA20") && strings.Contains(bName, "AES") {
return i != 0 // true for cipherSuitesPreferenceOrderNoAES // negative for cipherSuitesPreferenceOrderNoAES
if i != 0 {
return -1
} else {
return +1
}
} }
// AES-128 < AES-256 // AES-128 < AES-256
if strings.Contains(aName, "AES_128") && strings.Contains(bName, "AES_256") { if strings.Contains(aName, "AES_128") && strings.Contains(bName, "AES_256") {
return true return -1
} else if strings.Contains(aName, "AES_256") && strings.Contains(bName, "AES_128") { } else if strings.Contains(aName, "AES_256") && strings.Contains(bName, "AES_128") {
return false return +1
} }
// ECDSA < RSA // ECDSA < RSA
if aSuite.flags&suiteECSign != 0 && bSuite.flags&suiteECSign == 0 { if aSuite.flags&suiteECSign != 0 && bSuite.flags&suiteECSign == 0 {
return true return -1
} else if aSuite.flags&suiteECSign == 0 && bSuite.flags&suiteECSign != 0 { } else if aSuite.flags&suiteECSign == 0 && bSuite.flags&suiteECSign != 0 {
return false return +1
} }
t.Fatalf("two ciphersuites are equal by all criteria: %v and %v", aName, bName) t.Fatalf("two ciphersuites are equal by all criteria: %v and %v", aName, bName)
panic("unreachable") panic("unreachable")
} }
if !sort.SliceIsSorted(prefOrder, isBetter) { if !slices.IsSortedFunc(prefOrder, isBetter) {
t.Error("preference order is not sorted according to the rules") t.Error("preference order is not sorted according to the rules")
} }
} }

View File

@ -19,7 +19,7 @@ import (
"os/exec" "os/exec"
"reflect" "reflect"
"runtime" "runtime"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
@ -2064,7 +2064,7 @@ func chainsToStrings(chains [][]*Certificate) []string {
} }
chainStrings = append(chainStrings, strings.Join(names, " -> ")) chainStrings = append(chainStrings, strings.Join(names, " -> "))
} }
sort.Strings(chainStrings) slices.Sort(chainStrings)
return chainStrings return chainStrings
} }

View File

@ -10,7 +10,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"reflect" "reflect"
"sort" "slices"
"time" "time"
"unicode/utf8" "unicode/utf8"
) )
@ -105,15 +105,13 @@ func (s setEncoder) Encode(dst []byte) {
e.Encode(l[i]) e.Encode(l[i])
} }
sort.Slice(l, func(i, j int) bool { // Since we are using bytes.Compare to compare TLV encodings we
// Since we are using bytes.Compare to compare TLV encodings we // don't need to right pad s[i] and s[j] to the same length as
// don't need to right pad s[i] and s[j] to the same length as // suggested in X690. If len(s[i]) < len(s[j]) the length octet of
// suggested in X690. If len(s[i]) < len(s[j]) the length octet of // s[i], which is the first determining byte, will inherently be
// s[i], which is the first determining byte, will inherently be // smaller than the length octet of s[j]. This lets us skip the
// smaller than the length octet of s[j]. This lets us skip the // padding step.
// padding step. slices.SortFunc(l, bytes.Compare)
return bytes.Compare(l[i], l[j]) < 0
})
var off int var off int
for _, b := range l { for _, b := range l {

View File

@ -6,12 +6,13 @@ package gob
import ( import (
"bytes" "bytes"
"cmp"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"io" "io"
"math" "math"
"reflect" "reflect"
"sort" "slices"
"strings" "strings"
"testing" "testing"
) )
@ -1186,12 +1187,12 @@ func TestMarshalFloatMap(t *testing.T) {
for k, v := range m { for k, v := range m {
entries = append(entries, mapEntry{math.Float64bits(k), v}) entries = append(entries, mapEntry{math.Float64bits(k), v})
} }
sort.Slice(entries, func(i, j int) bool { slices.SortFunc(entries, func(a, b mapEntry) int {
ei, ej := entries[i], entries[j] r := cmp.Compare(a.keyBits, b.keyBits)
if ei.keyBits != ej.keyBits { if r != 0 {
return ei.keyBits < ej.keyBits return r
} }
return ei.value < ej.value return cmp.Compare(a.value, b.value)
}) })
return entries return entries
} }

View File

@ -12,7 +12,7 @@ import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"io" "io"
"sort" "slices"
"strings" "strings"
) )
@ -274,7 +274,7 @@ func Encode(out io.Writer, b *Block) error {
} }
} }
// For consistency of output, write other headers sorted by key. // For consistency of output, write other headers sorted by key.
sort.Strings(h) slices.Sort(h)
for _, k := range h { for _, k := range h {
if err := writeHeader(out, k, b.Headers[k]); err != nil { if err := writeHeader(out, k, b.Headers[k]); err != nil {
return err return err

View File

@ -6,7 +6,7 @@ package fmt
import ( import (
"errors" "errors"
"sort" "slices"
) )
// Errorf formats according to a format specifier and returns the string as a // Errorf formats according to a format specifier and returns the string as a
@ -34,7 +34,7 @@ func Errorf(format string, a ...any) error {
err = w err = w
default: default:
if p.reordered { if p.reordered {
sort.Ints(p.wrappedErrs) slices.Sort(p.wrappedErrs)
} }
var errs []error var errs []error
for i, argNum := range p.wrappedErrs { for i, argNum := range p.wrappedErrs {

View File

@ -6,26 +6,18 @@ package ast
import ( import (
"bytes" "bytes"
"cmp"
"fmt" "fmt"
"go/token" "go/token"
"sort" "slices"
"strings" "strings"
) )
type byPos []*CommentGroup
func (a byPos) Len() int { return len(a) }
func (a byPos) Less(i, j int) bool { return a[i].Pos() < a[j].Pos() }
func (a byPos) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// sortComments sorts the list of comment groups in source order. // sortComments sorts the list of comment groups in source order.
func sortComments(list []*CommentGroup) { func sortComments(list []*CommentGroup) {
// TODO(gri): Does it make sense to check for sorted-ness slices.SortFunc(list, func(a, b *CommentGroup) int {
// first (because we know that sorted-ness is return cmp.Compare(a.Pos(), b.Pos())
// very likely)? })
if orderedList := byPos(list); !sort.IsSorted(orderedList) {
sort.Sort(orderedList)
}
} }
// A CommentMap maps an AST node to a list of comment groups // A CommentMap maps an AST node to a list of comment groups
@ -64,11 +56,19 @@ func nodeList(n Node) []Node {
list = append(list, n) list = append(list, n)
return true return true
}) })
// Note: The current implementation assumes that Inspect traverses the // Note: The current implementation assumes that Inspect traverses the
// AST in depth-first and thus _source_ order. If AST traversal // AST in depth-first and thus _source_ order. If AST traversal
// does not follow source order, the sorting call below will be // does not follow source order, the sorting call below will be
// required. // required.
// sort.Sort(byInterval(list)) // slices.Sort(list, func(a, b Node) int {
// r := cmp.Compare(a.Pos(), b.Pos())
// if r != 0 {
// return r
// }
// return cmp.Compare(a.End(), b.End())
// })
return list return list
} }
@ -310,7 +310,13 @@ func (cmap CommentMap) String() string {
for node := range cmap { for node := range cmap {
nodes = append(nodes, node) nodes = append(nodes, node)
} }
sort.Sort(byInterval(nodes)) slices.SortFunc(nodes, func(a, b Node) int {
r := cmp.Compare(a.Pos(), b.Pos())
if r != 0 {
return r
}
return cmp.Compare(a.End(), b.End())
})
var buf strings.Builder var buf strings.Builder
fmt.Fprintln(&buf, "CommentMap {") fmt.Fprintln(&buf, "CommentMap {")

View File

@ -6,7 +6,7 @@ package ast
import ( import (
"go/token" "go/token"
"sort" "slices"
) )
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -357,7 +357,7 @@ func MergePackageFiles(pkg *Package, mode MergeMode) *File {
maxPos = f.FileEnd maxPos = f.FileEnd
} }
} }
sort.Strings(filenames) slices.Sort(filenames)
// Collect package comments from all package files into a single // Collect package comments from all package files into a single
// CommentGroup - the collected package documentation. In general // CommentGroup - the collected package documentation. In general

View File

@ -5,8 +5,9 @@
package ast package ast
import ( import (
"cmp"
"go/token" "go/token"
"sort" "slices"
"strconv" "strconv"
) )
@ -172,18 +173,20 @@ func sortSpecs(fset *token.FileSet, f *File, specs []Spec) []Spec {
// Reassign the import paths to have the same position sequence. // Reassign the import paths to have the same position sequence.
// Reassign each comment to the spec on the same line. // Reassign each comment to the spec on the same line.
// Sort the comments by new position. // Sort the comments by new position.
sort.Slice(specs, func(i, j int) bool { slices.SortFunc(specs, func(a, b Spec) int {
ipath := importPath(specs[i]) ipath := importPath(a)
jpath := importPath(specs[j]) jpath := importPath(b)
if ipath != jpath { r := cmp.Compare(ipath, jpath)
return ipath < jpath if r != 0 {
return r
} }
iname := importName(specs[i]) iname := importName(a)
jname := importName(specs[j]) jname := importName(b)
if iname != jname { r = cmp.Compare(iname, jname)
return iname < jname if r != 0 {
return r
} }
return importComment(specs[i]) < importComment(specs[j]) return cmp.Compare(importComment(a), importComment(b))
}) })
// Dedup. Thanks to our sorting, we can just consider // Dedup. Thanks to our sorting, we can just consider
@ -222,8 +225,8 @@ func sortSpecs(fset *token.FileSet, f *File, specs []Spec) []Spec {
} }
} }
sort.Slice(comments, func(i, j int) bool { slices.SortFunc(comments, func(a, b *CommentGroup) int {
return comments[i].Pos() < comments[j].Pos() return cmp.Compare(a.Pos(), b.Pos())
}) })
return specs return specs

View File

@ -24,7 +24,7 @@ import (
pathpkg "path" pathpkg "path"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"unicode" "unicode"
@ -1051,7 +1051,7 @@ Found:
for tag := range allTags { for tag := range allTags {
p.AllTags = append(p.AllTags, tag) p.AllTags = append(p.AllTags, tag)
} }
sort.Strings(p.AllTags) slices.Sort(p.AllTags)
p.EmbedPatterns, p.EmbedPatternPos = cleanDecls(embedPos) p.EmbedPatterns, p.EmbedPatternPos = cleanDecls(embedPos)
p.TestEmbedPatterns, p.TestEmbedPatternPos = cleanDecls(testEmbedPos) p.TestEmbedPatterns, p.TestEmbedPatternPos = cleanDecls(testEmbedPos)
@ -1066,10 +1066,10 @@ Found:
// The standard assemblers expect .s files. // The standard assemblers expect .s files.
if len(p.CgoFiles) > 0 { if len(p.CgoFiles) > 0 {
p.SFiles = append(p.SFiles, Sfiles...) p.SFiles = append(p.SFiles, Sfiles...)
sort.Strings(p.SFiles) slices.Sort(p.SFiles)
} else { } else {
p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, Sfiles...) p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, Sfiles...)
sort.Strings(p.IgnoredOtherFiles) slices.Sort(p.IgnoredOtherFiles)
} }
if badGoError != nil { if badGoError != nil {
@ -1111,7 +1111,7 @@ func uniq(list []string) []string {
} }
out := make([]string, len(list)) out := make([]string, len(list))
copy(out, list) copy(out, list)
sort.Strings(out) slices.Sort(out)
uniq := out[:0] uniq := out[:0]
for _, x := range out { for _, x := range out {
if len(uniq) == 0 || uniq[len(uniq)-1] != x { if len(uniq) == 0 || uniq[len(uniq)-1] != x {
@ -1525,7 +1525,7 @@ func cleanDecls(m map[string][]token.Position) ([]string, map[string][]token.Pos
for path := range m { for path := range m {
all = append(all, path) all = append(all, path)
} }
sort.Strings(all) slices.Sort(all)
return all, m return all, m
} }

View File

@ -17,7 +17,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sort" "slices"
"strings" "strings"
"testing" "testing"
) )
@ -140,7 +140,7 @@ var depsRules = `
< context < context
< TIME; < TIME;
TIME, io, path, sort TIME, io, path, slices
< io/fs; < io/fs;
# MATH is RUNTIME plus the basic math packages. # MATH is RUNTIME plus the basic math packages.
@ -264,7 +264,7 @@ var depsRules = `
< math/big; < math/big;
# compression # compression
FMT, encoding/binary, hash/adler32, hash/crc32 FMT, encoding/binary, hash/adler32, hash/crc32, sort
< compress/bzip2, compress/flate, compress/lzw, internal/zstd < compress/bzip2, compress/flate, compress/lzw, internal/zstd
< archive/zip, compress/gzip, compress/zlib; < archive/zip, compress/gzip, compress/zlib;
@ -277,7 +277,7 @@ var depsRules = `
< internal/lazytemplate; < internal/lazytemplate;
# regexp # regexp
FMT FMT, sort
< regexp/syntax < regexp/syntax
< regexp < regexp
< internal/lazyregexp; < internal/lazyregexp;
@ -290,7 +290,7 @@ var depsRules = `
< index/suffixarray; < index/suffixarray;
# executable parsing # executable parsing
FMT, encoding/binary, compress/zlib, internal/saferio, internal/zstd FMT, encoding/binary, compress/zlib, internal/saferio, internal/zstd, sort
< runtime/debug < runtime/debug
< debug/dwarf < debug/dwarf
< debug/elf, debug/gosym, debug/macho, debug/pe, debug/plan9obj, internal/xcoff < debug/elf, debug/gosym, debug/macho, debug/pe, debug/plan9obj, internal/xcoff
@ -298,7 +298,7 @@ var depsRules = `
< DEBUG; < DEBUG;
# go parser and friends. # go parser and friends.
FMT FMT, sort
< internal/gover < internal/gover
< go/version < go/version
< go/token < go/token
@ -307,7 +307,10 @@ var depsRules = `
< go/internal/typeparams; < go/internal/typeparams;
FMT FMT
< go/build/constraint, go/doc/comment; < go/build/constraint;
FMT, sort
< go/doc/comment;
go/internal/typeparams, go/build/constraint go/internal/typeparams, go/build/constraint
< go/parser; < go/parser;
@ -384,7 +387,7 @@ var depsRules = `
golang.org/x/net/lif, golang.org/x/net/lif,
golang.org/x/net/route; golang.org/x/net/route;
internal/bytealg, internal/itoa, math/bits, sort, strconv, unique internal/bytealg, internal/itoa, math/bits, slices, strconv, unique
< net/netip; < net/netip;
# net is unavoidable when doing any networking, # net is unavoidable when doing any networking,
@ -400,7 +403,8 @@ var depsRules = `
internal/poll, internal/poll,
internal/singleflight, internal/singleflight,
net/netip, net/netip,
os os,
sort
< net; < net;
fmt, unicode !< net; fmt, unicode !< net;
@ -580,7 +584,7 @@ var depsRules = `
< net/http/fcgi; < net/http/fcgi;
# Profiling # Profiling
FMT, compress/gzip, encoding/binary, text/tabwriter FMT, compress/gzip, encoding/binary, sort, text/tabwriter
< runtime/pprof; < runtime/pprof;
OS, compress/gzip, internal/lazyregexp OS, compress/gzip, internal/lazyregexp
@ -631,8 +635,11 @@ var depsRules = `
syscall syscall
< os/exec/internal/fdtest; < os/exec/internal/fdtest;
FMT, sort
< internal/diff;
FMT FMT
< internal/diff, internal/txtar; < internal/txtar;
# v2 execution trace parser. # v2 execution trace parser.
FMT FMT
@ -750,7 +757,7 @@ func TestDependencies(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
sort.Strings(all) slices.Sort(all)
sawImport := map[string]map[string]bool{} // from package => to package => true sawImport := map[string]map[string]bool{} // from package => to package => true
policy := depsPolicy(t) policy := depsPolicy(t)
@ -831,7 +838,7 @@ func findImports(pkg string) ([]string, error) {
} }
} }
} }
sort.Strings(imports) slices.Sort(imports)
return imports, nil return imports, nil
} }

View File

@ -9,7 +9,7 @@ import (
"go/constant" "go/constant"
"go/token" "go/token"
"math" "math"
"sort" "slices"
) )
func Example_complexNumbers() { func Example_complexNumbers() {
@ -98,9 +98,14 @@ func ExampleCompare() {
constant.MakeFromLiteral(`"a"`, token.STRING, 0), constant.MakeFromLiteral(`"a"`, token.STRING, 0),
} }
sort.Slice(vs, func(i, j int) bool { slices.SortFunc(vs, func(a, b constant.Value) int {
// Equivalent to vs[i] <= vs[j]. if constant.Compare(a, token.LSS, b) {
return constant.Compare(vs[i], token.LEQ, vs[j]) return -1
}
if constant.Compare(a, token.GTR, b) {
return +1
}
return 0
}) })
for _, v := range vs { for _, v := range vs {

View File

@ -7,7 +7,7 @@ package comment
import ( import (
"internal/diff" "internal/diff"
"internal/testenv" "internal/testenv"
"sort" "slices"
"strings" "strings"
"testing" "testing"
) )
@ -24,7 +24,7 @@ func TestStd(t *testing.T) {
list = append(list, pkg) list = append(list, pkg)
} }
} }
sort.Strings(list) slices.Sort(list)
have := strings.Join(stdPkgs, "\n") + "\n" have := strings.Join(stdPkgs, "\n") + "\n"
want := strings.Join(list, "\n") + "\n" want := strings.Join(list, "\n") + "\n"

View File

@ -7,11 +7,12 @@
package doc package doc
import ( import (
"cmp"
"go/ast" "go/ast"
"go/token" "go/token"
"internal/lazyregexp" "internal/lazyregexp"
"path" "path"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"unicode" "unicode"
@ -104,8 +105,8 @@ func Examples(testFiles ...*ast.File) []*Example {
list = append(list, flist...) list = append(list, flist...)
} }
// sort by name // sort by name
sort.Slice(list, func(i, j int) bool { slices.SortFunc(list, func(a, b *Example) int {
return list[i].Name < list[j].Name return cmp.Compare(a.Name, b.Name)
}) })
return list return list
} }
@ -309,11 +310,11 @@ func playExample(file *ast.File, f *ast.FuncDecl) *ast.File {
decls = append(decls, depDecls...) decls = append(decls, depDecls...)
decls = append(decls, funcDecl) decls = append(decls, funcDecl)
sort.Slice(decls, func(i, j int) bool { slices.SortFunc(decls, func(a, b ast.Decl) int {
return decls[i].Pos() < decls[j].Pos() return cmp.Compare(a.Pos(), b.Pos())
}) })
sort.Slice(comments, func(i, j int) bool { slices.SortFunc(comments, func(a, b *ast.CommentGroup) int {
return comments[i].Pos() < comments[j].Pos() return cmp.Compare(a.Pos(), b.Pos())
}) })
// Synthesize file. // Synthesize file.
@ -520,7 +521,9 @@ func findImportGroupStarts1(origImps []*ast.ImportSpec) []*ast.ImportSpec {
imps := make([]*ast.ImportSpec, len(origImps)) imps := make([]*ast.ImportSpec, len(origImps))
copy(imps, origImps) copy(imps, origImps)
// Assume the imports are sorted by position. // Assume the imports are sorted by position.
sort.Slice(imps, func(i, j int) bool { return imps[i].Pos() < imps[j].Pos() }) slices.SortFunc(imps, func(a, b *ast.ImportSpec) int {
return cmp.Compare(a.Pos(), b.Pos())
})
// Assume gofmt has been applied, so there is a blank line between adjacent imps // Assume gofmt has been applied, so there is a blank line between adjacent imps
// if and only if they are more than 2 positions apart (newline, tab). // if and only if they are more than 2 positions apart (newline, tab).
var groupStarts []*ast.ImportSpec var groupStarts []*ast.ImportSpec
@ -675,8 +678,8 @@ func classifyExamples(p *Package, examples []*Example) {
// Sort list of example according to the user-specified suffix name. // Sort list of example according to the user-specified suffix name.
for _, exs := range ids { for _, exs := range ids {
sort.Slice((*exs), func(i, j int) bool { slices.SortFunc(*exs, func(a, b *Example) int {
return (*exs)[i].Suffix < (*exs)[j].Suffix return cmp.Compare(a.Suffix, b.Suffix)
}) })
} }
} }

View File

@ -5,12 +5,13 @@
package doc package doc
import ( import (
"cmp"
"fmt" "fmt"
"go/ast" "go/ast"
"go/token" "go/token"
"internal/lazyregexp" "internal/lazyregexp"
"path" "path"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"unicode" "unicode"
@ -663,7 +664,7 @@ func (r *reader) readPackage(pkg *ast.Package, mode Mode) {
r.filenames[i] = filename r.filenames[i] = filename
i++ i++
} }
sort.Strings(r.filenames) slices.Sort(r.filenames)
// process files in sorted order // process files in sorted order
for _, filename := range r.filenames { for _, filename := range r.filenames {
@ -816,21 +817,6 @@ func (r *reader) cleanupTypes() {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Sorting // Sorting
type data struct {
n int
swap func(i, j int)
less func(i, j int) bool
}
func (d *data) Len() int { return d.n }
func (d *data) Swap(i, j int) { d.swap(i, j) }
func (d *data) Less(i, j int) bool { return d.less(i, j) }
// sortBy is a helper function for sorting.
func sortBy(less func(i, j int) bool, swap func(i, j int), n int) {
sort.Sort(&data{n, swap, less})
}
func sortedKeys(m map[string]int) []string { func sortedKeys(m map[string]int) []string {
list := make([]string, len(m)) list := make([]string, len(m))
i := 0 i := 0
@ -838,7 +824,7 @@ func sortedKeys(m map[string]int) []string {
list[i] = key list[i] = key
i++ i++
} }
sort.Strings(list) slices.Sort(list)
return list return list
} }
@ -863,16 +849,13 @@ func sortedValues(m []*Value, tok token.Token) []*Value {
} }
list = list[0:i] list = list[0:i]
sortBy( slices.SortFunc(list, func(a, b *Value) int {
func(i, j int) bool { r := strings.Compare(sortingName(a.Decl), sortingName(b.Decl))
if ni, nj := sortingName(list[i].Decl), sortingName(list[j].Decl); ni != nj { if r != 0 {
return ni < nj return r
} }
return list[i].order < list[j].order return cmp.Compare(a.order, b.order)
}, })
func(i, j int) { list[i], list[j] = list[j], list[i] },
len(list),
)
return list return list
} }
@ -893,11 +876,9 @@ func sortedTypes(m map[string]*namedType, allMethods bool) []*Type {
i++ i++
} }
sortBy( slices.SortFunc(list, func(a, b *Type) int {
func(i, j int) bool { return list[i].Name < list[j].Name }, return strings.Compare(a.Name, b.Name)
func(i, j int) { list[i], list[j] = list[j], list[i] }, })
len(list),
)
return list return list
} }
@ -925,11 +906,9 @@ func sortedFuncs(m methodSet, allMethods bool) []*Func {
} }
} }
list = list[0:i] list = list[0:i]
sortBy( slices.SortFunc(list, func(a, b *Func) int {
func(i, j int) bool { return list[i].Name < list[j].Name }, return strings.Compare(a.Name, b.Name)
func(i, j int) { list[i], list[j] = list[j], list[i] }, })
len(list),
)
return list return list
} }

View File

@ -250,9 +250,3 @@ func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDi
return return
} }
type byPath []*types.Package
func (a byPath) Len() int { return len(a) }
func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }

View File

@ -19,7 +19,7 @@ import (
"io" "io"
"math" "math"
"math/big" "math/big"
"sort" "slices"
"strings" "strings"
) )
@ -185,7 +185,7 @@ func iImportData(fset *token.FileSet, imports map[string]*types.Package, dataRea
for name := range p.pkgIndex[localpkg] { for name := range p.pkgIndex[localpkg] {
names = append(names, name) names = append(names, name)
} }
sort.Strings(names) slices.Sort(names)
for _, name := range names { for _, name := range names {
p.doDecl(localpkg, name) p.doDecl(localpkg, name)
} }
@ -205,7 +205,9 @@ func iImportData(fset *token.FileSet, imports map[string]*types.Package, dataRea
// record all referenced packages as imports // record all referenced packages as imports
list := append(([]*types.Package)(nil), pkgList[1:]...) list := append(([]*types.Package)(nil), pkgList[1:]...)
sort.Sort(byPath(list)) slices.SortFunc(list, func(a, b *types.Package) int {
return strings.Compare(a.Path(), b.Path())
})
localpkg.SetImports(list) localpkg.SetImports(list)
// package was imported completely and without errors // package was imported completely and without errors

View File

@ -9,7 +9,8 @@ import (
"go/types" "go/types"
"internal/godebug" "internal/godebug"
"internal/pkgbits" "internal/pkgbits"
"sort" "slices"
"strings"
) )
// A pkgReader holds the shared state for reading a unified IR package // A pkgReader holds the shared state for reading a unified IR package
@ -92,7 +93,9 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st
imps = append(imps, imp) imps = append(imps, imp)
} }
} }
sort.Sort(byPath(imps)) slices.SortFunc(imps, func(a, b *types.Package) int {
return strings.Compare(a.Path(), b.Path())
})
pkg.SetImports(imps) pkg.SetImports(imps)
pkg.MarkComplete() pkg.MarkComplete()

View File

@ -6,7 +6,7 @@ package printer
import ( import (
"go/build/constraint" "go/build/constraint"
"sort" "slices"
"text/tabwriter" "text/tabwriter"
) )
@ -108,7 +108,7 @@ func (p *printer) fixGoBuildLines() {
// Build sorted list of lines to delete from remainder of output. // Build sorted list of lines to delete from remainder of output.
toDelete := append(p.goBuild, p.plusBuild...) toDelete := append(p.goBuild, p.plusBuild...)
sort.Ints(toDelete) slices.Sort(toDelete)
// Collect output after insertion point, with lines deleted, into after. // Collect output after insertion point, with lines deleted, into after.
var after []byte var after []byte

View File

@ -5,8 +5,9 @@
package token package token
import ( import (
"cmp"
"fmt" "fmt"
"sort" "slices"
"strconv" "strconv"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -322,7 +323,15 @@ func (f *File) Line(p Pos) int {
} }
func searchLineInfos(a []lineInfo, x int) int { func searchLineInfos(a []lineInfo, x int) int {
return sort.Search(len(a), func(i int) bool { return a[i].Offset > x }) - 1 i, found := slices.BinarySearchFunc(a, x, func(a lineInfo, x int) int {
return cmp.Compare(a.Offset, x)
})
if !found {
// We want the lineInfo containing x, but if we didn't
// find x then i is the next one.
i--
}
return i
} }
// unpack returns the filename and line and column number for a file offset. // unpack returns the filename and line and column number for a file offset.
@ -516,7 +525,15 @@ func (s *FileSet) Iterate(f func(*File) bool) {
} }
func searchFiles(a []*File, x int) int { func searchFiles(a []*File, x int) int {
return sort.Search(len(a), func(i int) bool { return a[i].base > x }) - 1 i, found := slices.BinarySearchFunc(a, x, func(a *File, x int) int {
return cmp.Compare(a.base, x)
})
if !found {
// We want the File containing x, but if we didn't
// find x then i is the next one.
i--
}
return i
} }
func (s *FileSet) file(p Pos) *File { func (s *FileSet) file(p Pos) *File {

View File

@ -15,7 +15,7 @@ import (
"internal/testenv" "internal/testenv"
"reflect" "reflect"
"regexp" "regexp"
"sort" "slices"
"strings" "strings"
"sync" "sync"
"testing" "testing"
@ -693,8 +693,8 @@ func sortedInstances(m map[*ast.Ident]Instance) (instances []recordedInstance) {
for id, inst := range m { for id, inst := range m {
instances = append(instances, recordedInstance{id, inst}) instances = append(instances, recordedInstance{id, inst})
} }
sort.Slice(instances, func(i, j int) bool { slices.SortFunc(instances, func(a, b recordedInstance) int {
return CmpPos(instances[i].Ident.Pos(), instances[j].Ident.Pos()) < 0 return CmpPos(a.Ident.Pos(), b.Ident.Pos())
}) })
return instances return instances
} }

View File

@ -25,7 +25,7 @@ import (
"go/types" "go/types"
"log" "log"
"regexp" "regexp"
"sort" "slices"
"strings" "strings"
) )
@ -211,14 +211,14 @@ func fib(x int) int {
} }
var items []string var items []string
for obj, uses := range usesByObj { for obj, uses := range usesByObj {
sort.Strings(uses) slices.Sort(uses)
item := fmt.Sprintf("%s:\n defined at %s\n used at %s", item := fmt.Sprintf("%s:\n defined at %s\n used at %s",
types.ObjectString(obj, types.RelativeTo(pkg)), types.ObjectString(obj, types.RelativeTo(pkg)),
fset.Position(obj.Pos()), fset.Position(obj.Pos()),
strings.Join(uses, ", ")) strings.Join(uses, ", "))
items = append(items, item) items = append(items, item)
} }
sort.Strings(items) // sort by line:col, in effect slices.Sort(items) // sort by line:col, in effect
fmt.Println(strings.Join(items, "\n")) fmt.Println(strings.Join(items, "\n"))
fmt.Println() fmt.Println()
@ -237,7 +237,7 @@ func fib(x int) int {
mode(tv), tvstr) mode(tv), tvstr)
items = append(items, buf.String()) items = append(items, buf.String())
} }
sort.Strings(items) slices.Sort(items)
fmt.Println(strings.Join(items, "\n")) fmt.Println(strings.Join(items, "\n"))
// Output: // Output:

View File

@ -14,7 +14,7 @@ import (
"go/token" "go/token"
"internal/testenv" "internal/testenv"
"regexp" "regexp"
"sort" "slices"
"strings" "strings"
"testing" "testing"
@ -172,7 +172,7 @@ L7 uses var z int`
fact := fmt.Sprintf("L%d uses %s", fset.Position(id.Pos()).Line, obj) fact := fmt.Sprintf("L%d uses %s", fset.Position(id.Pos()).Line, obj)
facts = append(facts, fact) facts = append(facts, fact)
} }
sort.Strings(facts) slices.Sort(facts)
got := strings.Join(facts, "\n") got := strings.Join(facts, "\n")
if got != want { if got != want {

View File

@ -10,7 +10,7 @@ import (
"go/importer" "go/importer"
"go/token" "go/token"
"internal/testenv" "internal/testenv"
"sort" "slices"
"testing" "testing"
. "go/types" . "go/types"
@ -194,7 +194,7 @@ func TestResolveIdents(t *testing.T) {
} }
// check the expected set of idents that are simultaneously uses and defs // check the expected set of idents that are simultaneously uses and defs
sort.Strings(both) slices.Sort(both)
if got, want := fmt.Sprint(both), "[Mutex Stringer error]"; got != want { if got, want := fmt.Sprint(both), "[Mutex Stringer error]"; got != want {
t.Errorf("simultaneous uses/defs = %s, want %s", got, want) t.Errorf("simultaneous uses/defs = %s, want %s", got, want)
} }

View File

@ -22,6 +22,7 @@ import (
"io" "io"
"math" "math"
"regexp" "regexp"
"slices"
"sort" "sort"
) )
@ -308,7 +309,7 @@ func (x *Index) FindAllIndex(r *regexp.Regexp, n int) (result [][]int) {
if len(indices) == 0 { if len(indices) == 0 {
return return
} }
sort.Ints(indices) slices.Sort(indices)
pairs := make([]int, 2*len(indices)) pairs := make([]int, 2*len(indices))
result = make([][]int, len(indices)) result = make([][]int, len(indices))
count := 0 count := 0
@ -352,7 +353,7 @@ func (x *Index) FindAllIndex(r *regexp.Regexp, n int) (result [][]int) {
if len(indices) == 0 { if len(indices) == 0 {
return return
} }
sort.Ints(indices) slices.Sort(indices)
result = result[0:0] result = result[0:0]
prev := 0 prev := 0
for _, i := range indices { for _, i := range indices {

View File

@ -12,6 +12,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"slices"
"sort" "sort"
"strings" "strings"
"testing" "testing"
@ -141,7 +142,7 @@ func testLookup(t *testing.T, tc *testCase, x *Index, s string, n int) {
// we cannot simply check that the res and exp lists are equal // we cannot simply check that the res and exp lists are equal
// check that each result is in fact a correct match and there are no duplicates // check that each result is in fact a correct match and there are no duplicates
sort.Ints(res) slices.Sort(res)
for i, r := range res { for i, r := range res {
if r < 0 || len(tc.source) <= r { if r < 0 || len(tc.source) <= r {
t.Errorf("test %q, lookup %q, result %d (n = %d): index %d out of range [0, %d[", tc.name, s, i, n, r, len(tc.source)) t.Errorf("test %q, lookup %q, result %d (n = %d): index %d out of range [0, %d[", tc.name, s, i, n, r, len(tc.source))

View File

@ -31,11 +31,13 @@ package cformat
// emit coverage percentages. // emit coverage percentages.
import ( import (
"cmp"
"fmt" "fmt"
"internal/coverage" "internal/coverage"
"internal/coverage/cmerge" "internal/coverage/cmerge"
"io" "io"
"sort" "slices"
"strings"
"text/tabwriter" "text/tabwriter"
) )
@ -136,29 +138,27 @@ func (fm *Formatter) AddUnit(file string, fname string, isfnlit bool, unit cover
// include function name as part of the sorting criteria, the thinking // include function name as part of the sorting criteria, the thinking
// being that is better to provide things in the original source order. // being that is better to provide things in the original source order.
func (p *pstate) sortUnits(units []extcu) { func (p *pstate) sortUnits(units []extcu) {
sort.Slice(units, func(i, j int) bool { slices.SortFunc(units, func(ui, uj extcu) int {
ui := units[i]
uj := units[j]
ifile := p.funcs[ui.fnfid].file ifile := p.funcs[ui.fnfid].file
jfile := p.funcs[uj.fnfid].file jfile := p.funcs[uj.fnfid].file
if ifile != jfile { if r := strings.Compare(ifile, jfile); r != 0 {
return ifile < jfile return r
} }
// NB: not taking function literal flag into account here (no // NB: not taking function literal flag into account here (no
// need, since other fields are guaranteed to be distinct). // need, since other fields are guaranteed to be distinct).
if units[i].StLine != units[j].StLine { if r := cmp.Compare(ui.StLine, uj.StLine); r != 0 {
return units[i].StLine < units[j].StLine return r
} }
if units[i].EnLine != units[j].EnLine { if r := cmp.Compare(ui.EnLine, uj.EnLine); r != 0 {
return units[i].EnLine < units[j].EnLine return r
} }
if units[i].StCol != units[j].StCol { if r := cmp.Compare(ui.StCol, uj.StCol); r != 0 {
return units[i].StCol < units[j].StCol return r
} }
if units[i].EnCol != units[j].EnCol { if r := cmp.Compare(ui.EnCol, uj.EnCol); r != 0 {
return units[i].EnCol < units[j].EnCol return r
} }
return units[i].NxStmts < units[j].NxStmts return cmp.Compare(ui.NxStmts, uj.NxStmts)
}) })
} }
@ -178,7 +178,7 @@ func (fm *Formatter) EmitTextual(w io.Writer) error {
for importpath := range fm.pm { for importpath := range fm.pm {
pkgs = append(pkgs, importpath) pkgs = append(pkgs, importpath)
} }
sort.Strings(pkgs) slices.Sort(pkgs)
for _, importpath := range pkgs { for _, importpath := range pkgs {
p := fm.pm[importpath] p := fm.pm[importpath]
units := make([]extcu, 0, len(p.unitTable)) units := make([]extcu, 0, len(p.unitTable))
@ -220,7 +220,7 @@ func (fm *Formatter) EmitPercent(w io.Writer, covpkgs string, noteEmpty bool, ag
return nil return nil
} }
sort.Strings(pkgs) slices.Sort(pkgs)
var totalStmts, coveredStmts uint64 var totalStmts, coveredStmts uint64
for _, importpath := range pkgs { for _, importpath := range pkgs {
p := fm.pm[importpath] p := fm.pm[importpath]
@ -278,7 +278,7 @@ func (fm *Formatter) EmitFuncs(w io.Writer) error {
for importpath := range fm.pm { for importpath := range fm.pm {
pkgs = append(pkgs, importpath) pkgs = append(pkgs, importpath)
} }
sort.Strings(pkgs) slices.Sort(pkgs)
// Emit functions for each package, sorted by import path. // Emit functions for each package, sorted by import path.
for _, importpath := range pkgs { for _, importpath := range pkgs {

View File

@ -14,7 +14,7 @@ import (
"internal/coverage/uleb128" "internal/coverage/uleb128"
"io" "io"
"os" "os"
"sort" "slices"
) )
// This package contains APIs and helpers for encoding initial portions // This package contains APIs and helpers for encoding initial portions
@ -126,7 +126,7 @@ func (cfw *CoverageDataWriter) writeSegmentPreamble(args map[string]string, ws *
for k := range args { for k := range args {
akeys = append(akeys, k) akeys = append(akeys, k)
} }
sort.Strings(akeys) slices.Sort(akeys)
wrULEB128 := func(v uint) error { wrULEB128 := func(v uint) error {
cfw.tmp = cfw.tmp[:0] cfw.tmp = cfw.tmp[:0]

View File

@ -5,13 +5,15 @@
package pods package pods
import ( import (
"cmp"
"fmt" "fmt"
"internal/coverage" "internal/coverage"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"sort" "slices"
"strconv" "strconv"
"strings"
) )
// Pod encapsulates a set of files emitted during the executions of a // Pod encapsulates a set of files emitted during the executions of a
@ -165,11 +167,11 @@ func collectPodsImpl(files []string, dirIndices []int, warn bool) []Pod {
} }
pods := make([]Pod, 0, len(mm)) pods := make([]Pod, 0, len(mm))
for _, p := range mm { for _, p := range mm {
sort.Slice(p.elements, func(i, j int) bool { slices.SortFunc(p.elements, func(a, b fileWithAnnotations) int {
if p.elements[i].origin != p.elements[j].origin { if r := cmp.Compare(a.origin, b.origin); r != 0 {
return p.elements[i].origin < p.elements[j].origin return r
} }
return p.elements[i].file < p.elements[j].file return strings.Compare(a.file, b.file)
}) })
pod := Pod{ pod := Pod{
MetaFile: p.mf, MetaFile: p.mf,
@ -184,8 +186,8 @@ func collectPodsImpl(files []string, dirIndices []int, warn bool) []Pod {
} }
pods = append(pods, pod) pods = append(pods, pod)
} }
sort.Slice(pods, func(i, j int) bool { slices.SortFunc(pods, func(a, b Pod) int {
return pods[i].MetaFile < pods[j].MetaFile return strings.Compare(a.MetaFile, b.MetaFile)
}) })
return pods return pods
} }

View File

@ -42,8 +42,9 @@
package dag package dag
import ( import (
"cmp"
"fmt" "fmt"
"sort" "slices"
"strings" "strings"
) )
@ -84,7 +85,9 @@ func (g *Graph) Edges(from string) []string {
for k := range g.edges[from] { for k := range g.edges[from] {
edges = append(edges, k) edges = append(edges, k)
} }
sort.Slice(edges, func(i, j int) bool { return g.byLabel[edges[i]] < g.byLabel[edges[j]] }) slices.SortFunc(edges, func(a, b string) int {
return cmp.Compare(g.byLabel[a], g.byLabel[b])
})
return edges return edges
} }

View File

@ -5,12 +5,13 @@
package fmtsort_test package fmtsort_test
import ( import (
"cmp"
"fmt" "fmt"
"internal/fmtsort" "internal/fmtsort"
"math" "math"
"reflect" "reflect"
"runtime" "runtime"
"sort" "slices"
"strings" "strings"
"testing" "testing"
"unsafe" "unsafe"
@ -196,8 +197,8 @@ func makeChans() []chan int {
for i := range cs { for i := range cs {
pin.Pin(reflect.ValueOf(cs[i]).UnsafePointer()) pin.Pin(reflect.ValueOf(cs[i]).UnsafePointer())
} }
sort.Slice(cs, func(i, j int) bool { slices.SortFunc(cs, func(a, b chan int) int {
return uintptr(reflect.ValueOf(cs[i]).UnsafePointer()) < uintptr(reflect.ValueOf(cs[j]).UnsafePointer()) return cmp.Compare(reflect.ValueOf(a).Pointer(), reflect.ValueOf(b).Pointer())
}) })
return cs return cs
} }

View File

@ -13,7 +13,7 @@ import (
"os/exec" "os/exec"
"reflect" "reflect"
"runtime/metrics" "runtime/metrics"
"sort" "slices"
"strings" "strings"
"testing" "testing"
) )
@ -115,7 +115,7 @@ func TestCmdBisect(t *testing.T) {
want = append(want, fmt.Sprintf("godebug_test.go:%d", i+1)) want = append(want, fmt.Sprintf("godebug_test.go:%d", i+1))
} }
} }
sort.Strings(want) slices.Sort(want)
var have []string var have []string
for _, line := range strings.Split(string(out), "\n") { for _, line := range strings.Split(string(out), "\n") {
@ -123,7 +123,7 @@ func TestCmdBisect(t *testing.T) {
have = append(have, line[strings.LastIndex(line, "godebug_test.go:"):]) have = append(have, line[strings.LastIndex(line, "godebug_test.go:"):])
} }
} }
sort.Strings(have) slices.Sort(have)
if !reflect.DeepEqual(have, want) { if !reflect.DeepEqual(have, want) {
t.Errorf("bad bisect output:\nhave %v\nwant %v\ncomplete output:\n%s", have, want, string(out)) t.Errorf("bad bisect output:\nhave %v\nwant %v\ncomplete output:\n%s", have, want, string(out))

View File

@ -126,20 +126,6 @@ func (l *orderEventList) Less(i, j int) bool {
return (*l)[i].ev.Ts < (*l)[j].ev.Ts return (*l)[i].ev.Ts < (*l)[j].ev.Ts
} }
type eventList []Event
func (l *eventList) Len() int {
return len(*l)
}
func (l *eventList) Less(i, j int) bool {
return (*l)[i].Ts < (*l)[j].Ts
}
func (l *eventList) Swap(i, j int) {
(*l)[i], (*l)[j] = (*l)[j], (*l)[i]
}
func (h *orderEventList) Push(x orderEvent) { func (h *orderEventList) Push(x orderEvent) {
*h = append(*h, x) *h = append(*h, x)
heapUp(h, len(*h)-1) heapUp(h, len(*h)-1)

View File

@ -13,6 +13,7 @@ package oldtrace
import ( import (
"bytes" "bytes"
"cmp"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
@ -20,6 +21,7 @@ import (
"internal/trace/version" "internal/trace/version"
"io" "io"
"math" "math"
"slices"
"sort" "sort"
) )
@ -368,7 +370,9 @@ func (p *parser) parseEventBatches() (Events, error) {
// with original timestamps corresponding to when ReadTrace pulled the data // with original timestamps corresponding to when ReadTrace pulled the data
// off of the profBuf queue. Re-sort them by the timestamp we captured // off of the profBuf queue. Re-sort them by the timestamp we captured
// inside the signal handler. // inside the signal handler.
sort.Sort((*eventList)(&p.cpuSamples)) slices.SortFunc(p.cpuSamples, func(a, b Event) int {
return cmp.Compare(a.Ts, b.Ts)
})
allProcs := make([]proc, 0, len(p.batchOffsets)) allProcs := make([]proc, 0, len(p.batchOffsets))
for pid := range p.batchOffsets { for pid := range p.batchOffsets {

View File

@ -5,8 +5,9 @@
package trace package trace
import ( import (
"cmp"
"math" "math"
"sort" "slices"
) )
// mud is an updatable mutator utilization distribution. // mud is an updatable mutator utilization distribution.
@ -166,8 +167,8 @@ func (d *mud) invCumulativeSum(y float64) (float64, bool) {
// Sort edges. // Sort edges.
edges := d.unsorted edges := d.unsorted
sort.Slice(edges, func(i, j int) bool { slices.SortFunc(edges, func(a, b edge) int {
return edges[i].x < edges[j].x return cmp.Compare(a.x, b.x)
}) })
// Merge with sorted edges. // Merge with sorted edges.
d.unsorted = nil d.unsorted = nil

View File

@ -5,7 +5,8 @@
package trace package trace
import ( import (
"sort" "cmp"
"slices"
"strings" "strings"
"time" "time"
) )
@ -593,16 +594,19 @@ func (s *Summarizer) Finalize() *Summary {
g.finalize(s.lastTs, nil) g.finalize(s.lastTs, nil)
// Sort based on region start time. // Sort based on region start time.
sort.Slice(g.Regions, func(i, j int) bool { slices.SortFunc(g.Regions, func(a, b *UserRegionSummary) int {
x := g.Regions[i].Start x := a.Start
y := g.Regions[j].Start y := b.Start
if x == nil { if x == nil {
return true if y == nil {
return 0
}
return -1
} }
if y == nil { if y == nil {
return false return +1
} }
return x.Time() < y.Time() return cmp.Compare(x.Time(), y.Time())
}) })
g.goroutineSummary = nil g.goroutineSummary = nil
} }

View File

@ -6,7 +6,8 @@ package fs
import ( import (
"errors" "errors"
"sort" "internal/bytealg"
"slices"
) )
// ReadDirFS is the interface implemented by a file system // ReadDirFS is the interface implemented by a file system
@ -42,7 +43,9 @@ func ReadDir(fsys FS, name string) ([]DirEntry, error) {
} }
list, err := dir.ReadDir(-1) list, err := dir.ReadDir(-1)
sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() }) slices.SortFunc(list, func(a, b DirEntry) int {
return bytealg.CompareString(a.Name(), b.Name())
})
return list, err return list, err
} }

View File

@ -14,7 +14,8 @@ import (
"io" "io"
"io/fs" "io/fs"
"os" "os"
"sort" "slices"
"strings"
) )
// ReadAll reads from r until an error or EOF and returns the data it read. // ReadAll reads from r until an error or EOF and returns the data it read.
@ -76,7 +77,9 @@ func ReadDir(dirname string) ([]fs.FileInfo, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() }) slices.SortFunc(list, func(a, b os.FileInfo) int {
return strings.Compare(a.Name(), b.Name())
})
return list, nil return list, nil
} }

View File

@ -8,7 +8,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
. "io" . "io"
"sort" "slices"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -418,6 +418,6 @@ func sortBytesInGroups(b []byte, n int) []byte {
groups = append(groups, b[:n]) groups = append(groups, b[:n])
b = b[n:] b = b[n:]
} }
sort.Slice(groups, func(i, j int) bool { return bytes.Compare(groups[i], groups[j]) < 0 }) slices.SortFunc(groups, bytes.Compare)
return bytes.Join(groups, nil) return bytes.Join(groups, nil)
} }

View File

@ -10,7 +10,7 @@ package big
import ( import (
"fmt" "fmt"
"sort" "slices"
"testing" "testing"
) )
@ -78,7 +78,7 @@ func (x Bits) norm() Bits {
z = append(z, b) z = append(z, b)
} }
} }
sort.Ints([]int(z)) slices.Sort([]int(z))
return z return z
} }

View File

@ -7,7 +7,7 @@ package mime
import ( import (
"errors" "errors"
"fmt" "fmt"
"sort" "slices"
"strings" "strings"
"unicode" "unicode"
) )
@ -37,7 +37,7 @@ func FormatMediaType(t string, param map[string]string) string {
for a := range param { for a := range param {
attrs = append(attrs, a) attrs = append(attrs, a)
} }
sort.Strings(attrs) slices.Sort(attrs)
for _, attribute := range attrs { for _, attribute := range attrs {
value := param[attribute] value := param[attribute]

View File

@ -11,7 +11,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/textproto" "net/textproto"
"sort" "slices"
"strings" "strings"
) )
@ -111,7 +111,7 @@ func (w *Writer) CreatePart(header textproto.MIMEHeader) (io.Writer, error) {
for k := range header { for k := range header {
keys = append(keys, k) keys = append(keys, k)
} }
sort.Strings(keys) slices.Sort(keys)
for _, k := range keys { for _, k := range keys {
for _, v := range header[k] { for _, v := range header[k] {
fmt.Fprintf(&b, "%s: %s\r\n", k, v) fmt.Fprintf(&b, "%s: %s\r\n", k, v)

View File

@ -12,7 +12,7 @@ import (
"io" "io"
"os/exec" "os/exec"
"regexp" "regexp"
"sort" "slices"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -197,7 +197,7 @@ func TestExhaustive(t *testing.T) {
for k, v := range res { for k, v := range res {
outcomes = append(outcomes, fmt.Sprintf("%v: %d", k, v)) outcomes = append(outcomes, fmt.Sprintf("%v: %d", k, v))
} }
sort.Strings(outcomes) slices.Sort(outcomes)
got := strings.Join(outcomes, "\n") got := strings.Join(outcomes, "\n")
want := `OK: 28934 want := `OK: 28934
invalid bytes after =: 3949 invalid bytes after =: 3949

View File

@ -7,7 +7,7 @@ package mime
import ( import (
"fmt" "fmt"
"sort" "slices"
"strings" "strings"
"sync" "sync"
) )
@ -150,7 +150,7 @@ func ExtensionsByType(typ string) ([]string, error) {
return nil, nil return nil, nil
} }
ret := append([]string(nil), s.([]string)...) ret := append([]string(nil), s.([]string)...)
sort.Strings(ret) slices.Sort(ret)
return ret, nil return ret, nil
} }

View File

@ -5,9 +5,10 @@
package net package net
import ( import (
"cmp"
"internal/bytealg" "internal/bytealg"
"internal/itoa" "internal/itoa"
"sort" "slices"
_ "unsafe" // for go:linkname _ "unsafe" // for go:linkname
"golang.org/x/net/dns/dnsmessage" "golang.org/x/net/dns/dnsmessage"
@ -160,12 +161,6 @@ type SRV struct {
// byPriorityWeight sorts SRV records by ascending priority and weight. // byPriorityWeight sorts SRV records by ascending priority and weight.
type byPriorityWeight []*SRV type byPriorityWeight []*SRV
func (s byPriorityWeight) Len() int { return len(s) }
func (s byPriorityWeight) Less(i, j int) bool {
return s[i].Priority < s[j].Priority || (s[i].Priority == s[j].Priority && s[i].Weight < s[j].Weight)
}
func (s byPriorityWeight) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// shuffleByWeight shuffles SRV records by weight using the algorithm // shuffleByWeight shuffles SRV records by weight using the algorithm
// described in RFC 2782. // described in RFC 2782.
func (addrs byPriorityWeight) shuffleByWeight() { func (addrs byPriorityWeight) shuffleByWeight() {
@ -192,7 +187,12 @@ func (addrs byPriorityWeight) shuffleByWeight() {
// sort reorders SRV records as specified in RFC 2782. // sort reorders SRV records as specified in RFC 2782.
func (addrs byPriorityWeight) sort() { func (addrs byPriorityWeight) sort() {
sort.Sort(addrs) slices.SortFunc(addrs, func(a, b *SRV) int {
if r := cmp.Compare(a.Priority, b.Priority); r != 0 {
return r
}
return cmp.Compare(a.Weight, b.Weight)
})
i := 0 i := 0
for j := 1; j < len(addrs); j++ { for j := 1; j < len(addrs); j++ {
if addrs[i].Priority != addrs[j].Priority { if addrs[i].Priority != addrs[j].Priority {
@ -209,20 +209,18 @@ type MX struct {
Pref uint16 Pref uint16
} }
// byPref implements sort.Interface to sort MX records by preference // byPref sorts MX records by preference
type byPref []*MX type byPref []*MX
func (s byPref) Len() int { return len(s) }
func (s byPref) Less(i, j int) bool { return s[i].Pref < s[j].Pref }
func (s byPref) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// sort reorders MX records as specified in RFC 5321. // sort reorders MX records as specified in RFC 5321.
func (s byPref) sort() { func (s byPref) sort() {
for i := range s { for i := range s {
j := randIntn(i + 1) j := randIntn(i + 1)
s[i], s[j] = s[j], s[i] s[i], s[j] = s[j], s[i]
} }
sort.Sort(s) slices.SortFunc(s, func(a, b *MX) int {
return cmp.Compare(a.Pref, b.Pref)
})
} }
// An NS represents a single DNS NS record. // An NS represents a single DNS NS record.

View File

@ -10,7 +10,7 @@ import (
"net/http" "net/http"
"os" "os"
"path" "path"
"sort" "slices"
"strings" "strings"
"time" "time"
) )
@ -67,7 +67,7 @@ func testCGI() {
for k := range params { for k := range params {
keys = append(keys, k) keys = append(keys, k)
} }
sort.Strings(keys) slices.Sort(keys)
for _, key := range keys { for _, key := range keys {
fmt.Printf("param-%s=%s\r\n", key, params.Get(key)) fmt.Printf("param-%s=%s\r\n", key, params.Get(key))
} }
@ -77,7 +77,7 @@ func testCGI() {
for k := range envs { for k := range envs {
keys = append(keys, k) keys = append(keys, k)
} }
sort.Strings(keys) slices.Sort(keys)
for _, key := range keys { for _, key := range keys {
fmt.Printf("env-%s=%s\r\n", key, envs[key]) fmt.Printf("env-%s=%s\r\n", key, envs[key])
} }

View File

@ -27,7 +27,7 @@ import (
"os" "os"
"reflect" "reflect"
"runtime" "runtime"
"sort" "slices"
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -693,7 +693,7 @@ func testTrailersClientToServer(t *testing.T, mode testMode) {
for k := range r.Trailer { for k := range r.Trailer {
decl = append(decl, k) decl = append(decl, k)
} }
sort.Strings(decl) slices.Sort(decl)
slurp, err := io.ReadAll(r.Body) slurp, err := io.ReadAll(r.Body)
if err != nil { if err != nil {

View File

@ -6,13 +6,14 @@
package cookiejar package cookiejar
import ( import (
"cmp"
"errors" "errors"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"net/http/internal/ascii" "net/http/internal/ascii"
"net/url" "net/url"
"sort" "slices"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -210,15 +211,14 @@ func (j *Jar) cookies(u *url.URL, now time.Time) (cookies []*http.Cookie) {
// sort according to RFC 6265 section 5.4 point 2: by longest // sort according to RFC 6265 section 5.4 point 2: by longest
// path and then by earliest creation time. // path and then by earliest creation time.
sort.Slice(selected, func(i, j int) bool { slices.SortFunc(selected, func(a, b entry) int {
s := selected if r := cmp.Compare(b.Path, a.Path); r != 0 {
if len(s[i].Path) != len(s[j].Path) { return r
return len(s[i].Path) > len(s[j].Path)
} }
if ret := s[i].Creation.Compare(s[j].Creation); ret != 0 { if r := a.Creation.Compare(b.Creation); r != 0 {
return ret < 0 return r
} }
return s[i].seqNum < s[j].seqNum return cmp.Compare(a.seqNum, b.seqNum)
}) })
for _, e := range selected { for _, e := range selected {
cookies = append(cookies, &http.Cookie{Name: e.Name, Value: e.Value, Quoted: e.Quoted}) cookies = append(cookies, &http.Cookie{Name: e.Name, Value: e.Value, Quoted: e.Quoted})

View File

@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
"sort" "slices"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -412,7 +412,7 @@ func (test jarTest) run(t *testing.T, jar *Jar) {
cs = append(cs, cookie.Name+"="+v) cs = append(cs, cookie.Name+"="+v)
} }
} }
sort.Strings(cs) slices.Sort(cs)
got := strings.Join(cs, " ") got := strings.Join(cs, " ")
// Make sure jar content matches our expectations. // Make sure jar content matches our expectations.

View File

@ -22,7 +22,7 @@ import (
"net/url" "net/url"
"os" "os"
"reflect" "reflect"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -202,9 +202,9 @@ func TestReverseProxyStripHeadersPresentInConnection(t *testing.T) {
} }
} }
} }
sort.Strings(cf) slices.Sort(cf)
expectedValues := []string{"Upgrade", someConnHeader, fakeConnectionToken} expectedValues := []string{"Upgrade", someConnHeader, fakeConnectionToken}
sort.Strings(expectedValues) slices.Sort(expectedValues)
if !reflect.DeepEqual(cf, expectedValues) { if !reflect.DeepEqual(cf, expectedValues) {
t.Errorf("handler modified header %q = %q; want %q", "Connection", cf, expectedValues) t.Errorf("handler modified header %q = %q; want %q", "Connection", cf, expectedValues)
} }

View File

@ -12,7 +12,7 @@ import (
"net/netip" "net/netip"
"reflect" "reflect"
"runtime" "runtime"
"sort" "slices"
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -428,7 +428,7 @@ func TestLookupLongTXT(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
sort.Strings(txts) slices.Sort(txts)
want := []string{ want := []string{
strings.Repeat("abcdefghijklmnopqrstuvwxyABCDEFGHJIKLMNOPQRSTUVWXY", 10), strings.Repeat("abcdefghijklmnopqrstuvwxyABCDEFGHJIKLMNOPQRSTUVWXY", 10),
"gophers rule", "gophers rule",

View File

@ -5,6 +5,7 @@
package net package net
import ( import (
"cmp"
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
@ -13,7 +14,7 @@ import (
"os/exec" "os/exec"
"reflect" "reflect"
"regexp" "regexp"
"sort" "slices"
"strings" "strings"
"syscall" "syscall"
"testing" "testing"
@ -65,8 +66,14 @@ func TestNSLookupMX(t *testing.T) {
if err != nil { if err != nil {
t.Skipf("skipping failed nslookup %s test: %s", server, err) t.Skipf("skipping failed nslookup %s test: %s", server, err)
} }
sort.Sort(byPrefAndHost(expected)) byPrefAndHost := func(a, b *MX) int {
sort.Sort(byPrefAndHost(mx)) if r := cmp.Compare(a.Pref, b.Pref); r != 0 {
return r
}
return strings.Compare(a.Host, b.Host)
}
slices.SortFunc(expected, byPrefAndHost)
slices.SortFunc(mx, byPrefAndHost)
if !reflect.DeepEqual(expected, mx) { if !reflect.DeepEqual(expected, mx) {
t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(mx)) t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(mx))
} }
@ -109,8 +116,11 @@ func TestNSLookupNS(t *testing.T) {
if err != nil { if err != nil {
t.Skipf("skipping failed nslookup %s test: %s", server, err) t.Skipf("skipping failed nslookup %s test: %s", server, err)
} }
sort.Sort(byHost(expected)) byHost := func(a, b *NS) int {
sort.Sort(byHost(ns)) return strings.Compare(a.Host, b.Host)
}
slices.SortFunc(expected, byHost)
slices.SortFunc(ns, byHost)
if !reflect.DeepEqual(expected, ns) { if !reflect.DeepEqual(expected, ns) {
t.Errorf("different results %s:\texp:%v\tgot:%v", toJson(server), toJson(expected), ns) t.Errorf("different results %s:\texp:%v\tgot:%v", toJson(server), toJson(expected), ns)
} }
@ -132,8 +142,8 @@ func TestNSLookupTXT(t *testing.T) {
if err != nil { if err != nil {
t.Skipf("skipping failed nslookup %s test: %s", server, err) t.Skipf("skipping failed nslookup %s test: %s", server, err)
} }
sort.Strings(expected) slices.Sort(expected)
sort.Strings(txt) slices.Sort(txt)
if !reflect.DeepEqual(expected, txt) { if !reflect.DeepEqual(expected, txt) {
t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(txt)) t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(txt))
} }
@ -158,8 +168,8 @@ func TestLookupLocalPTR(t *testing.T) {
if err != nil { if err != nil {
t.Skipf("skipping failed lookup %s test: %s", addr.String(), err) t.Skipf("skipping failed lookup %s test: %s", addr.String(), err)
} }
sort.Strings(expected) slices.Sort(expected)
sort.Strings(names) slices.Sort(names)
if !reflect.DeepEqual(expected, names) { if !reflect.DeepEqual(expected, names) {
t.Errorf("different results %s:\texp:%v\tgot:%v", addr, toJson(expected), toJson(names)) t.Errorf("different results %s:\texp:%v\tgot:%v", addr, toJson(expected), toJson(names))
} }
@ -189,31 +199,14 @@ func TestLookupPTR(t *testing.T) {
t.Logf("skipping failed lookup %s test: %s", addr, err) t.Logf("skipping failed lookup %s test: %s", addr, err)
continue continue
} }
sort.Strings(expected) slices.Sort(expected)
sort.Strings(names) slices.Sort(names)
if !reflect.DeepEqual(expected, names) { if !reflect.DeepEqual(expected, names) {
t.Errorf("different results %s:\texp:%v\tgot:%v", addr, toJson(expected), toJson(names)) t.Errorf("different results %s:\texp:%v\tgot:%v", addr, toJson(expected), toJson(names))
} }
} }
} }
type byPrefAndHost []*MX
func (s byPrefAndHost) Len() int { return len(s) }
func (s byPrefAndHost) Less(i, j int) bool {
if s[i].Pref != s[j].Pref {
return s[i].Pref < s[j].Pref
}
return s[i].Host < s[j].Host
}
func (s byPrefAndHost) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type byHost []*NS
func (s byHost) Len() int { return len(s) }
func (s byHost) Less(i, j int) bool { return s[i].Host < s[j].Host }
func (s byHost) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func nslookup(qtype, name string) (string, error) { func nslookup(qtype, name string) (string, error) {
var out strings.Builder var out strings.Builder
var err strings.Builder var err strings.Builder

View File

@ -10,7 +10,7 @@ import (
"net/internal/socktest" "net/internal/socktest"
"os" "os"
"runtime" "runtime"
"sort" "slices"
"strings" "strings"
"sync" "sync"
"testing" "testing"
@ -193,7 +193,7 @@ func runningGoroutines() []string {
} }
gss = append(gss, stack) gss = append(gss, stack)
} }
sort.Strings(gss) slices.Sort(gss)
return gss return gss
} }

View File

@ -13,7 +13,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"regexp" "regexp"
"sort" "slices"
"strings" "strings"
"syscall" "syscall"
"testing" "testing"
@ -286,7 +286,7 @@ func TestInterfacesWithNetsh(t *testing.T) {
for _, ifi := range ift { for _, ifi := range ift {
have = append(have, toString(ifi.Name, ifi.Flags&FlagUp != 0)) have = append(have, toString(ifi.Name, ifi.Flags&FlagUp != 0))
} }
sort.Strings(have) slices.Sort(have)
ifaces := make(map[string]bool) ifaces := make(map[string]bool)
err = netshInterfaceIPShowInterface("ipv6", ifaces) err = netshInterfaceIPShowInterface("ipv6", ifaces)
@ -301,7 +301,7 @@ func TestInterfacesWithNetsh(t *testing.T) {
for name, isup := range ifaces { for name, isup := range ifaces {
want = append(want, toString(name, isup)) want = append(want, toString(name, isup))
} }
sort.Strings(want) slices.Sort(want)
if strings.Join(want, "/") != strings.Join(have, "/") { if strings.Join(want, "/") != strings.Join(have, "/") {
t.Fatalf("unexpected interface list %q, want %q", have, want) t.Fatalf("unexpected interface list %q, want %q", have, want)
@ -483,12 +483,12 @@ func TestInterfaceAddrsWithNetsh(t *testing.T) {
} }
} }
} }
sort.Strings(have) slices.Sort(have)
want := netshInterfaceIPv4ShowAddress(ifi.Name, outIPV4) want := netshInterfaceIPv4ShowAddress(ifi.Name, outIPV4)
wantIPv6 := netshInterfaceIPv6ShowAddress(ifi.Name, outIPV6) wantIPv6 := netshInterfaceIPv6ShowAddress(ifi.Name, outIPV6)
want = append(want, wantIPv6...) want = append(want, wantIPv6...)
sort.Strings(want) slices.Sort(want)
if strings.Join(want, "/") != strings.Join(have, "/") { if strings.Join(want, "/") != strings.Join(have, "/") {
t.Errorf("%s: unexpected addresses list %q, want %q", ifi.Name, have, want) t.Errorf("%s: unexpected addresses list %q, want %q", ifi.Name, have, want)

View File

@ -14,7 +14,6 @@ import (
. "net/netip" . "net/netip"
"reflect" "reflect"
"slices" "slices"
"sort"
"strings" "strings"
"testing" "testing"
"unique" "unique"
@ -885,7 +884,7 @@ func TestAddrLessCompare(t *testing.T) {
mustIP("8.8.8.8"), mustIP("8.8.8.8"),
mustIP("::1%foo"), mustIP("::1%foo"),
} }
sort.Slice(values, func(i, j int) bool { return values[i].Less(values[j]) }) slices.SortFunc(values, Addr.Compare)
got := fmt.Sprintf("%s", values) got := fmt.Sprintf("%s", values)
want := `[invalid IP 1.2.3.4 8.8.8.8 ::1 ::1%foo ::2]` want := `[invalid IP 1.2.3.4 8.8.8.8 ::1 ::1%foo ::2]`
if got != want { if got != want {
@ -936,7 +935,7 @@ func TestAddrPortCompare(t *testing.T) {
mustIPPort("8.8.8.8:8080"), mustIPPort("8.8.8.8:8080"),
mustIPPort("[::1%foo]:1024"), mustIPPort("[::1%foo]:1024"),
} }
slices.SortFunc(values, func(a, b AddrPort) int { return a.Compare(b) }) slices.SortFunc(values, AddrPort.Compare)
got := fmt.Sprintf("%s", values) got := fmt.Sprintf("%s", values)
want := `[invalid AddrPort 1.2.3.4:443 8.8.8.8:8080 [::1]:80 [::1%foo]:1024 [::2]:80]` want := `[invalid AddrPort 1.2.3.4:443 8.8.8.8:8080 [::1]:80 [::1%foo]:1024 [::2]:80]`
if got != want { if got != want {
@ -988,7 +987,7 @@ func TestPrefixCompare(t *testing.T) {
mustPrefix("fe80::/48"), mustPrefix("fe80::/48"),
mustPrefix("1.2.0.0/24"), mustPrefix("1.2.0.0/24"),
} }
slices.SortFunc(values, func(a, b Prefix) int { return a.Compare(b) }) slices.SortFunc(values, Prefix.Compare)
got := fmt.Sprintf("%s", values) got := fmt.Sprintf("%s", values)
want := `[invalid Prefix 1.2.0.0/16 1.2.0.0/24 1.2.3.0/24 fe80::/48 fe80::/64 fe90::/64]` want := `[invalid Prefix 1.2.0.0/16 1.2.0.0/24 1.2.3.0/24 fe80::/48 fe80::/64 fe90::/64]`
if got != want { if got != want {

View File

@ -13,7 +13,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"reflect" "reflect"
"sort" "slices"
"testing" "testing"
"time" "time"
@ -97,7 +97,7 @@ func sortedIPStrings(ips []IP) []string {
for i, ip := range ips { for i, ip := range ips {
ret[i] = ip.String() ret[i] = ip.String()
} }
sort.Strings(ret) slices.Sort(ret)
return ret return ret
} }

View File

@ -13,7 +13,8 @@ import (
"fmt" "fmt"
"html/template" "html/template"
"net/http" "net/http"
"sort" "slices"
"strings"
) )
const debugText = `<html> const debugText = `<html>
@ -51,7 +52,7 @@ type methodArray []debugMethod
type debugService struct { type debugService struct {
Service *service Service *service
Name string Name string
Method methodArray Method []debugMethod
} }
type serviceArray []debugService type serviceArray []debugService
@ -74,15 +75,19 @@ func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) {
var services serviceArray var services serviceArray
server.serviceMap.Range(func(snamei, svci any) bool { server.serviceMap.Range(func(snamei, svci any) bool {
svc := svci.(*service) svc := svci.(*service)
ds := debugService{svc, snamei.(string), make(methodArray, 0, len(svc.method))} ds := debugService{svc, snamei.(string), make([]debugMethod, 0, len(svc.method))}
for mname, method := range svc.method { for mname, method := range svc.method {
ds.Method = append(ds.Method, debugMethod{method, mname}) ds.Method = append(ds.Method, debugMethod{method, mname})
} }
sort.Sort(ds.Method) slices.SortFunc(ds.Method, func(a, b debugMethod) int {
return strings.Compare(a.Name, b.Name)
})
services = append(services, ds) services = append(services, ds)
return true return true
}) })
sort.Sort(services) slices.SortFunc(services, func(a, b debugService) int {
return strings.Compare(a.Name, b.Name)
})
err := debug.Execute(w, services) err := debug.Execute(w, services)
if err != nil { if err != nil {
fmt.Fprintln(w, "rpc: error executing template:", err.Error()) fmt.Fprintln(w, "rpc: error executing template:", err.Error())

View File

@ -14,7 +14,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"path" "path"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
) )
@ -994,7 +994,7 @@ func (v Values) Encode() string {
for k := range v { for k := range v {
keys = append(keys, k) keys = append(keys, k)
} }
sort.Strings(keys) slices.Sort(keys)
for _, k := range keys { for _, k := range keys {
vs := v[k] vs := v[k]
keyEscaped := QueryEscape(k) keyEscaped := QueryEscape(k)

View File

@ -5,10 +5,11 @@
package os package os
import ( import (
"internal/bytealg"
"internal/filepathlite" "internal/filepathlite"
"io" "io"
"io/fs" "io/fs"
"sort" "slices"
) )
type readdirMode int type readdirMode int
@ -122,7 +123,9 @@ func ReadDir(name string) ([]DirEntry, error) {
defer f.Close() defer f.Close()
dirs, err := f.ReadDir(-1) dirs, err := f.ReadDir(-1)
sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() }) slices.SortFunc(dirs, func(a, b DirEntry) int {
return bytealg.CompareString(a.Name(), b.Name())
})
return dirs, err return dirs, err
} }

View File

@ -19,7 +19,7 @@ import (
"reflect" "reflect"
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"sort" "slices"
"strings" "strings"
"sync" "sync"
"syscall" "syscall"
@ -808,7 +808,7 @@ func TestReaddirStatFailures(t *testing.T) {
for i, fi := range fis { for i, fi := range fis {
s[i] = fi.Name() s[i] = fi.Name()
} }
sort.Strings(s) slices.Sort(s)
return s return s
} }

View File

@ -20,7 +20,6 @@ import (
"reflect" "reflect"
"runtime" "runtime"
"slices" "slices"
"sort"
"strings" "strings"
"syscall" "syscall"
"testing" "testing"
@ -664,7 +663,7 @@ func TestOpenVolumeName(t *testing.T) {
chdir(t, tmpdir) chdir(t, tmpdir)
want := []string{"file1", "file2", "file3", "gopher.txt"} want := []string{"file1", "file2", "file3", "gopher.txt"}
sort.Strings(want) slices.Sort(want)
for _, name := range want { for _, name := range want {
err := os.WriteFile(filepath.Join(tmpdir, name), nil, 0777) err := os.WriteFile(filepath.Join(tmpdir, name), nil, 0777)
if err != nil { if err != nil {
@ -682,7 +681,7 @@ func TestOpenVolumeName(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
sort.Strings(have) slices.Sort(have)
if strings.Join(want, "/") != strings.Join(have, "/") { if strings.Join(want, "/") != strings.Join(have, "/") {
t.Fatalf("unexpected file list %q, want %q", have, want) t.Fatalf("unexpected file list %q, want %q", have, want)

View File

@ -8,7 +8,7 @@ package user
import ( import (
"fmt" "fmt"
"sort" "slices"
"strings" "strings"
"testing" "testing"
) )
@ -92,8 +92,8 @@ func checkSameIDs(t *testing.T, got, want []string) {
t.Errorf("ID list mismatch: got %v; want %v", got, want) t.Errorf("ID list mismatch: got %v; want %v", got, want)
return return
} }
sort.Strings(got) slices.Sort(got)
sort.Strings(want) slices.Sort(want)
mismatch := -1 mismatch := -1
for i, g := range want { for i, g := range want {
if got[i] != g { if got[i] != g {

View File

@ -9,7 +9,7 @@ import (
"internal/filepathlite" "internal/filepathlite"
"os" "os"
"runtime" "runtime"
"sort" "slices"
"strings" "strings"
"unicode/utf8" "unicode/utf8"
) )
@ -345,7 +345,7 @@ func glob(dir, pattern string, matches []string) (m []string, e error) {
defer d.Close() defer d.Close()
names, _ := d.Readdirnames(-1) names, _ := d.Readdirnames(-1)
sort.Strings(names) slices.Sort(names)
for _, n := range names { for _, n := range names {
matched, err := Match(pattern, n) matched, err := Match(pattern, n)

View File

@ -17,7 +17,7 @@ import (
"internal/filepathlite" "internal/filepathlite"
"io/fs" "io/fs"
"os" "os"
"sort" "slices"
) )
const ( const (
@ -444,7 +444,7 @@ func readDirNames(dirname string) ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
sort.Strings(names) slices.Sort(names)
return names, nil return names, nil
} }

View File

@ -22,7 +22,7 @@ import (
"reflect/internal/example1" "reflect/internal/example1"
"reflect/internal/example2" "reflect/internal/example2"
"runtime" "runtime"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -6282,7 +6282,7 @@ func TestMapOfGCKeys(t *testing.T) {
for _, kv := range v.MapKeys() { for _, kv := range v.MapKeys() {
out = append(out, int(kv.Elem().Interface().(uintptr))) out = append(out, int(kv.Elem().Interface().(uintptr)))
} }
sort.Ints(out) slices.Sort(out)
for j, k := range out { for j, k := range out {
if k != i*n+j { if k != i*n+j {
t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j) t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
@ -7861,7 +7861,7 @@ func iterateToString(it *MapIter) string {
line := fmt.Sprintf("%v: %v", it.Key(), it.Value()) line := fmt.Sprintf("%v: %v", it.Key(), it.Value())
got = append(got, line) got = append(got, line)
} }
sort.Strings(got) slices.Sort(got)
return "[" + strings.Join(got, ", ") + "]" return "[" + strings.Join(got, ", ") + "]"
} }

View File

@ -6,7 +6,7 @@ package debug
import ( import (
"runtime" "runtime"
"sort" "slices"
"time" "time"
) )
@ -69,7 +69,7 @@ func ReadGCStats(stats *GCStats) {
// See the allocation at the top of the function. // See the allocation at the top of the function.
sorted := stats.Pause[n : n+n] sorted := stats.Pause[n : n+n]
copy(sorted, stats.Pause) copy(sorted, stats.Pause)
sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] }) slices.Sort(sorted)
nq := len(stats.PauseQuantiles) - 1 nq := len(stats.PauseQuantiles) - 1
for i := 0; i < nq; i++ { for i := 0; i < nq; i++ {
stats.PauseQuantiles[i] = sorted[len(sorted)*i/nq] stats.PauseQuantiles[i] = sorted[len(sorted)*i/nq]

View File

@ -11,7 +11,7 @@ import (
"reflect" "reflect"
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"sort" "slices"
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -548,9 +548,7 @@ func BenchmarkReadMemStatsLatency(b *testing.B) {
b.ReportMetric(0, "allocs/op") b.ReportMetric(0, "allocs/op")
// Sort latencies then report percentiles. // Sort latencies then report percentiles.
sort.Slice(latencies, func(i, j int) bool { slices.Sort(latencies)
return latencies[i] < latencies[j]
})
b.ReportMetric(float64(latencies[len(latencies)*50/100]), "p50-ns") b.ReportMetric(float64(latencies[len(latencies)*50/100]), "p50-ns")
b.ReportMetric(float64(latencies[len(latencies)*90/100]), "p90-ns") b.ReportMetric(float64(latencies[len(latencies)*90/100]), "p90-ns")
b.ReportMetric(float64(latencies[len(latencies)*99/100]), "p99-ns") b.ReportMetric(float64(latencies[len(latencies)*99/100]), "p99-ns")

View File

@ -13,7 +13,7 @@ import (
"os" "os"
"reflect" "reflect"
"runtime" "runtime"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -388,8 +388,8 @@ func TestBigItems(t *testing.T) {
values[i] = v[37] values[i] = v[37]
i++ i++
} }
sort.Strings(keys[:]) slices.Sort(keys[:])
sort.Strings(values[:]) slices.Sort(values[:])
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
if keys[i] != fmt.Sprintf("string%02d", i) { if keys[i] != fmt.Sprintf("string%02d", i) {
t.Errorf("#%d: missing key: %v", i, keys[i]) t.Errorf("#%d: missing key: %v", i, keys[i])

View File

@ -7,7 +7,7 @@ package pprof
import ( import (
"context" "context"
"fmt" "fmt"
"sort" "slices"
"strings" "strings"
) )
@ -49,7 +49,7 @@ func (l *labelMap) String() string {
keyVals = append(keyVals, fmt.Sprintf("%q:%q", k, v)) keyVals = append(keyVals, fmt.Sprintf("%q:%q", k, v))
} }
sort.Strings(keyVals) slices.Sort(keyVals)
return "{" + strings.Join(keyVals, ", ") + "}" return "{" + strings.Join(keyVals, ", ") + "}"
} }

View File

@ -74,11 +74,13 @@ package pprof
import ( import (
"bufio" "bufio"
"cmp"
"fmt" "fmt"
"internal/abi" "internal/abi"
"internal/profilerecord" "internal/profilerecord"
"io" "io"
"runtime" "runtime"
"slices"
"sort" "sort"
"strings" "strings"
"sync" "sync"
@ -273,7 +275,9 @@ func Profiles() []*Profile {
all = append(all, p) all = append(all, p)
} }
sort.Slice(all, func(i, j int) bool { return all[i].name < all[j].name }) slices.SortFunc(all, func(a, b *Profile) int {
return strings.Compare(a.name, b.name)
})
return all return all
} }
@ -373,15 +377,7 @@ func (p *Profile) WriteTo(w io.Writer, debug int) error {
p.mu.Unlock() p.mu.Unlock()
// Map order is non-deterministic; make output deterministic. // Map order is non-deterministic; make output deterministic.
sort.Slice(all, func(i, j int) bool { slices.SortFunc(all, slices.Compare)
t, u := all[i], all[j]
for k := 0; k < len(t) && k < len(u); k++ {
if t[k] != u[k] {
return t[k] < u[k]
}
}
return len(t) < len(u)
})
return printCountProfile(w, debug, p.name, stackProfile(all)) return printCountProfile(w, debug, p.name, stackProfile(all))
} }
@ -609,7 +605,9 @@ func writeHeapInternal(w io.Writer, debug int, defaultSampleType string) error {
return writeHeapProto(w, p, int64(runtime.MemProfileRate), defaultSampleType) return writeHeapProto(w, p, int64(runtime.MemProfileRate), defaultSampleType)
} }
sort.Slice(p, func(i, j int) bool { return p[i].InUseBytes() > p[j].InUseBytes() }) slices.SortFunc(p, func(a, b profilerecord.MemProfileRecord) int {
return cmp.Compare(a.InUseBytes(), b.InUseBytes())
})
b := bufio.NewWriter(w) b := bufio.NewWriter(w)
tw := tabwriter.NewWriter(b, 1, 8, 1, '\t', 0) tw := tabwriter.NewWriter(b, 1, 8, 1, '\t', 0)
@ -909,7 +907,9 @@ func writeProfileInternal(w io.Writer, debug int, name string, runtimeProfile fu
} }
} }
sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles }) slices.SortFunc(p, func(a, b profilerecord.BlockProfileRecord) int {
return cmp.Compare(b.Cycles, a.Cycles)
})
if debug <= 0 { if debug <= 0 {
return printCountCycleProfile(w, "contentions", "delay", p) return printCountCycleProfile(w, "contentions", "delay", p)

View File

@ -10,7 +10,7 @@ import (
"io" "io"
. "runtime" . "runtime"
"runtime/debug" "runtime/debug"
"sort" "slices"
"strings" "strings"
"sync" "sync"
"testing" "testing"
@ -382,9 +382,7 @@ func BenchmarkGoroutineProfile(b *testing.B) {
b.StopTimer() b.StopTimer()
// Sort latencies then report percentiles. // Sort latencies then report percentiles.
sort.Slice(latencies, func(i, j int) bool { slices.Sort(latencies)
return latencies[i] < latencies[j]
})
b.ReportMetric(float64(latencies[len(latencies)*50/100]), "p50-ns") b.ReportMetric(float64(latencies[len(latencies)*50/100]), "p50-ns")
b.ReportMetric(float64(latencies[len(latencies)*90/100]), "p90-ns") b.ReportMetric(float64(latencies[len(latencies)*90/100]), "p90-ns")
b.ReportMetric(float64(latencies[len(latencies)*99/100]), "p99-ns") b.ReportMetric(float64(latencies[len(latencies)*99/100]), "p99-ns")

View File

@ -11,7 +11,7 @@ package sync_test
import ( import (
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"sort" "slices"
. "sync" . "sync"
"sync/atomic" "sync/atomic"
"testing" "testing"
@ -338,7 +338,7 @@ func BenchmarkPoolSTW(b *testing.B) {
} }
// Get pause time stats. // Get pause time stats.
sort.Slice(pauses, func(i, j int) bool { return pauses[i] < pauses[j] }) slices.Sort(pauses)
var total uint64 var total uint64
for _, ns := range pauses { for _, ns := range pauses {
total += ns total += ns

View File

@ -12,7 +12,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
@ -71,7 +71,7 @@ func TestDirent(t *testing.T) {
} }
} }
sort.Strings(names) slices.Sort(names)
t.Logf("names: %q", names) t.Logf("names: %q", names)
if len(names) != 10 { if len(names) != 10 {
@ -138,8 +138,8 @@ func TestDirentRepeat(t *testing.T) {
} }
// Check results // Check results
sort.Strings(files) slices.Sort(files)
sort.Strings(files2) slices.Sort(files2)
if strings.Join(files, "|") != strings.Join(files2, "|") { if strings.Join(files, "|") != strings.Join(files2, "|") {
t.Errorf("bad file list: want\n%q\ngot\n%q", files, files2) t.Errorf("bad file list: want\n%q\ngot\n%q", files, files2)
} }

View File

@ -10,7 +10,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"sort" "slices"
"strings" "strings"
"syscall" "syscall"
"testing" "testing"
@ -76,8 +76,8 @@ func testGetdirentries(t *testing.T, count int) {
} }
names = append(names, ".", "..") // Getdirentries returns these also names = append(names, ".", "..") // Getdirentries returns these also
sort.Strings(names) slices.Sort(names)
sort.Strings(names2) slices.Sort(names2)
if strings.Join(names, ":") != strings.Join(names2, ":") { if strings.Join(names, ":") != strings.Join(names2, ":") {
t.Errorf("names don't match\n names: %q\nnames2: %q", names, names2) t.Errorf("names don't match\n names: %q\nnames2: %q", names, names2)
} }

View File

@ -13,7 +13,7 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -484,7 +484,7 @@ func compareStatus(filter, expect string) error {
// https://github.com/golang/go/issues/46145 // https://github.com/golang/go/issues/46145
// Containers don't reliably output this line in sorted order so manually sort and compare that. // Containers don't reliably output this line in sorted order so manually sort and compare that.
a := strings.Split(line[8:], " ") a := strings.Split(line[8:], " ")
sort.Strings(a) slices.Sort(a)
got := strings.Join(a, " ") got := strings.Join(a, " ")
if got == expected[8:] { if got == expected[8:] {
foundAThread = true foundAThread = true

View File

@ -12,7 +12,7 @@ import (
"math" "math"
"os" "os"
"runtime" "runtime"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -443,7 +443,7 @@ func (r BenchmarkResult) String() string {
} }
extraKeys = append(extraKeys, k) extraKeys = append(extraKeys, k)
} }
sort.Strings(extraKeys) slices.Sort(extraKeys)
for _, k := range extraKeys { for _, k := range extraKeys {
buf.WriteByte('\t') buf.WriteByte('\t')
prettyPrint(buf, r.Extra[k], k) prettyPrint(buf, r.Extra[k], k)

View File

@ -6,8 +6,9 @@ package testing_test
import ( import (
"bytes" "bytes"
"cmp"
"runtime" "runtime"
"sort" "slices"
"strings" "strings"
"sync/atomic" "sync/atomic"
"testing" "testing"
@ -168,9 +169,9 @@ func ExampleB_ReportMetric() {
var compares int64 var compares int64
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
s := []int{5, 4, 3, 2, 1} s := []int{5, 4, 3, 2, 1}
sort.Slice(s, func(i, j int) bool { slices.SortFunc(s, func(a, b int) int {
compares++ compares++
return s[i] < s[j] return cmp.Compare(a, b)
}) })
} }
// This metric is per-operation, so divide by b.N and // This metric is per-operation, so divide by b.N and
@ -190,12 +191,12 @@ func ExampleB_ReportMetric_parallel() {
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
for pb.Next() { for pb.Next() {
s := []int{5, 4, 3, 2, 1} s := []int{5, 4, 3, 2, 1}
sort.Slice(s, func(i, j int) bool { slices.SortFunc(s, func(a, b int) int {
// Because RunParallel runs the function many // Because RunParallel runs the function many
// times in parallel, we must increment the // times in parallel, we must increment the
// counter atomically to avoid racing writes. // counter atomically to avoid racing writes.
compares.Add(1) compares.Add(1)
return s[i] < s[j] return cmp.Compare(a, b)
}) })
} }
}) })

View File

@ -6,7 +6,7 @@ package testing
import ( import (
"fmt" "fmt"
"sort" "slices"
"strings" "strings"
"time" "time"
) )
@ -47,7 +47,7 @@ func runExamples(matchString func(pat, str string) (bool, error), examples []Int
func sortLines(output string) string { func sortLines(output string) string {
lines := strings.Split(output, "\n") lines := strings.Split(output, "\n")
sort.Strings(lines) slices.Sort(lines)
return strings.Join(lines, "\n") return strings.Join(lines, "\n")
} }

View File

@ -8,7 +8,7 @@ import (
"io" "io"
"io/fs" "io/fs"
"path" "path"
"sort" "slices"
"strings" "strings"
"time" "time"
) )
@ -100,8 +100,8 @@ func (fsys MapFS) Open(name string) (fs.File, error) {
for name := range need { for name := range need {
list = append(list, mapFileInfo{name, &MapFile{Mode: fs.ModeDir | 0555}}) list = append(list, mapFileInfo{name, &MapFile{Mode: fs.ModeDir | 0555}})
} }
sort.Slice(list, func(i, j int) bool { slices.SortFunc(list, func(a, b mapFileInfo) int {
return list[i].name < list[j].name return strings.Compare(a.name, b.name)
}) })
if file == nil { if file == nil {

View File

@ -12,7 +12,7 @@ import (
"io/fs" "io/fs"
"path" "path"
"reflect" "reflect"
"sort" "slices"
"strings" "strings"
"testing/iotest" "testing/iotest"
) )
@ -78,7 +78,7 @@ func testFS(fsys fs.FS, expected ...string) error {
list = append(list, k) list = append(list, k)
} }
} }
sort.Strings(list) slices.Sort(list)
if len(list) > 15 { if len(list) > 15 {
list = append(list[:10], "...") list = append(list[:10], "...")
} }
@ -362,9 +362,9 @@ func (t *fsTester) checkGlob(dir string, list []fs.DirEntry) {
return return
} }
if !sort.StringsAreSorted(names) { if !slices.IsSorted(names) {
t.errorf("%s: Glob(%#q): unsorted output:\n%s", dir, glob, strings.Join(names, "\n")) t.errorf("%s: Glob(%#q): unsorted output:\n%s", dir, glob, strings.Join(names, "\n"))
sort.Strings(names) slices.Sort(names)
} }
var problems []string var problems []string
@ -488,11 +488,11 @@ func (t *fsTester) checkDirList(dir, desc string, list1, list2 []fs.DirEntry) {
return return
} }
sort.Slice(diffs, func(i, j int) bool { slices.SortFunc(diffs, func(a, b string) int {
fi := strings.Fields(diffs[i]) fa := strings.Fields(a)
fj := strings.Fields(diffs[j]) fb := strings.Fields(b)
// sort by name (i < j) and then +/- (j < i, because + < -) // sort by name (i < j) and then +/- (j < i, because + < -)
return fi[1]+" "+fj[0] < fj[1]+" "+fi[0] return strings.Compare(fa[1]+" "+fb[0], fb[1]+" "+fa[0])
}) })
t.errorf("%s: diff %s:\n\t%s", dir, desc, strings.Join(diffs, "\n\t")) t.errorf("%s: diff %s:\n\t%s", dir, desc, strings.Join(diffs, "\n\t"))

View File

@ -10,7 +10,8 @@ import (
"io/fs" "io/fs"
"os" "os"
"path/filepath" "path/filepath"
"sort" "slices"
"strings"
"testing" "testing"
) )
@ -61,8 +62,8 @@ func (f *shuffledFile) ReadDir(n int) ([]fs.DirEntry, error) {
// //
// We do this to make sure that the TestFS test suite is not affected by the // We do this to make sure that the TestFS test suite is not affected by the
// order of directory entries. // order of directory entries.
sort.Slice(dirents, func(i, j int) bool { slices.SortFunc(dirents, func(a, b fs.DirEntry) int {
return dirents[i].Name() > dirents[j].Name() return strings.Compare(b.Name(), a.Name())
}) })
return dirents, err return dirents, err
} }

View File

@ -383,7 +383,7 @@ import (
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"runtime/trace" "runtime/trace"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -2382,7 +2382,7 @@ func runningList() []string {
list = append(list, fmt.Sprintf("%s (%v)", k.(string), highPrecisionTimeSince(v.(highPrecisionTime)).Round(time.Second))) list = append(list, fmt.Sprintf("%s (%v)", k.(string), highPrecisionTimeSince(v.(highPrecisionTime)).Round(time.Second)))
return true return true
}) })
sort.Strings(list) slices.Sort(list)
return list return list
} }

View File

@ -21,7 +21,8 @@ import (
"log" "log"
"net/http" "net/http"
"os" "os"
"sort" "slices"
"strings"
"text/template" "text/template"
"time" "time"
) )
@ -109,8 +110,8 @@ func main() {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
sort.Slice(zs, func(i, j int) bool { slices.SortFunc(zs, func(a, b *zone) int {
return zs[i].UnixName < zs[j].UnixName return strings.Compare(a.UnixName, b.UnixName)
}) })
var v = struct { var v = struct {
URL string URL string