"fmt"
"internal/goversion"
"internal/testenv"
- "sort"
+ "slices"
"strings"
"sync"
"testing"
for id, inst := range m {
instances = append(instances, recordedInstance{id, inst})
}
- sort.Slice(instances, func(i, j int) bool {
- return CmpPos(instances[i].Name.Pos(), instances[j].Name.Pos()) < 0
+ slices.SortFunc(instances, func(a, b recordedInstance) int {
+ return CmpPos(a.Name.Pos(), b.Name.Pos())
})
return instances
}
// look for matching scope description
desc := kind + ":" + strings.Join(scope.Names(), " ")
- found := false
- for _, d := range test.scopes {
- if desc == d {
- found = true
- break
- }
- }
- if !found {
+ if !slices.Contains(test.scopes, desc) {
t.Errorf("package %s: no matching scope found for %s", name, desc)
}
}
t.Errorf("%s: got object = %v; want none", test.src, f)
}
}
- if !sameSlice(index, test.index) {
+ if !slices.Equal(index, test.index) {
t.Errorf("%s: got index = %v; want %v", test.src, index, test.index)
}
if indirect != test.indirect {
_, _, _ = LookupFieldOrMethod(T, false, pkg, "M") // verify that LookupFieldOrMethod terminates
}
-func sameSlice(a, b []int) bool {
- if len(a) != len(b) {
- return false
- }
- for i, x := range a {
- if x != b[i] {
- return false
- }
- }
- return true
-}
-
// newDefined creates a new defined type named T with the given underlying type.
func newDefined(underlying Type) *Named {
tname := NewTypeName(nopos, nil, "T", nil)
"go/constant"
"internal/buildcfg"
. "internal/types/errors"
+ "slices"
)
func (check *Checker) declare(scope *Scope, id *syntax.Name, obj Object, pos syntax.Pos) {
if debug {
// obj must be one of lhs
- found := false
- for _, lhs := range lhs {
- if obj == lhs {
- found = true
- break
- }
- }
- if !found {
+ if !slices.Contains(lhs, obj) {
panic("inconsistent lhs")
}
}
"fmt"
"log"
"regexp"
- "sort"
+ "slices"
"strings"
)
}
var items []string
for obj, uses := range usesByObj {
- sort.Strings(uses)
+ slices.Sort(uses)
item := fmt.Sprintf("%s:\n defined at %s\n used at %s",
types2.ObjectString(obj, types2.RelativeTo(pkg)),
obj.Pos(),
strings.Join(uses, ", "))
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()
// mode(tv), tvstr)
// items = append(items, buf.String())
// }
- // sort.Strings(items)
+ // slices.Sort(items)
// fmt.Println(strings.Join(items, "\n"))
// Output:
import (
"cmd/compile/internal/syntax"
"fmt"
+ "slices"
"strings"
)
// be able to use it either.
if check.conf.Error != nil {
defer func() {
- assert(inferred == nil || len(inferred) == len(tparams) && !containsNil(inferred))
+ assert(inferred == nil || len(inferred) == len(tparams) && !slices.Contains(inferred, nil))
}()
}
assert(params.Len() == len(args))
// If we already have all type arguments, we're done.
- if len(targs) == n && !containsNil(targs) {
+ if len(targs) == n && !slices.Contains(targs, nil) {
return targs
}
return
}
-// containsNil reports whether list contains a nil entry.
-func containsNil(list []Type) bool {
- for _, t := range list {
- if t == nil {
- return true
- }
- }
- return false
-}
-
// renameTParams renames the type parameters in the given type such that each type
// parameter is given a new identity. renameTParams returns the new type parameters
// and updated type. If the result type is unchanged from the argument type, none
}
case *TypeParam:
- return tparamIndex(w.tparams, t) >= 0
+ return slices.Index(w.tparams, t) >= 0
default:
panic(fmt.Sprintf("unexpected %T", typ))
// in w.tparams, iterative substitution will lead to infinite expansion.
// Nil out the corresponding type which effectively kills the cycle.
if tpar, _ := typ.(*TypeParam); tpar != nil {
- if i := tparamIndex(w.tparams, tpar); i >= 0 {
+ if i := slices.Index(w.tparams, tpar); i >= 0 {
// cycle through tpar
w.inferred[i] = nil
}
}
case *TypeParam:
- if i := tparamIndex(w.tparams, t); i >= 0 && w.inferred[i] != nil {
+ if i := slices.Index(w.tparams, t); i >= 0 && w.inferred[i] != nil {
w.typ(w.inferred[i])
}
w.typ(v.typ)
}
}
-
-// If tpar is a type parameter in list, tparamIndex returns the index
-// of the type parameter in list. Otherwise the result is < 0.
-func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
- for i, p := range list {
- if p == tpar {
- return i
- }
- }
- return -1
-}
"fmt"
"internal/testenv"
"regexp"
- "sort"
+ "slices"
"strings"
"testing"
fact := fmt.Sprintf("L%d uses %s", id.Pos().Line(), obj)
facts = append(facts, fact)
}
- sort.Strings(facts)
+ slices.Sort(facts)
got := strings.Join(facts, "\n")
if got != want {
import (
"cmd/compile/internal/syntax"
. "internal/types/errors"
+ "slices"
)
// labels checks correct label use in body.
}
jumpsOverVarDecl := func(jmp *syntax.BranchStmt) bool {
- if varDeclPos.IsKnown() {
- for _, bad := range badJumps {
- if jmp == bad {
- return true
- }
- }
- }
- return false
+ return varDeclPos.IsKnown() && slices.Contains(badJumps, jmp)
}
var stmtBranches func(syntax.Stmt)
return samePkg(obj.pkg, pkg)
}
-// less reports whether object a is ordered before object b.
+// cmp reports whether object a is ordered before object b.
+// cmp returns:
+//
+// -1 if a is before b
+// 0 if a is equivalent to b
+// +1 if a is behind b
//
// Objects are ordered nil before non-nil, exported before
// non-exported, then by name, and finally (for non-exported
// functions) by package path.
-func (a *object) less(b *object) bool {
+func (a *object) cmp(b *object) int {
if a == b {
- return false
+ return 0
}
// Nil before non-nil.
if a == nil {
- return true
+ return -1
}
if b == nil {
- return false
+ return +1
}
// Exported functions before non-exported.
ea := isExported(a.name)
eb := isExported(b.name)
if ea != eb {
- return ea
+ if ea {
+ return -1
+ }
+ return +1
}
// Order by name and then (for non-exported names) by package.
if a.name != b.name {
- return a.name < b.name
+ return strings.Compare(a.name, b.name)
}
if !ea {
- return a.pkg.path < b.pkg.path
+ return strings.Compare(a.pkg.path, b.pkg.path)
}
- return false
+ return 0
}
// A PkgName represents an imported Go package.
package types2
-import "unicode"
+import (
+ "slices"
+ "unicode"
+)
// isValid reports whether t is a valid type.
func isValid(t Type) bool { return Unalias(t) != Typ[Invalid] }
// Instantiations are identical if their origin and type arguments are
// identical.
func identicalInstance(xorig Type, xargs []Type, yorig Type, yargs []Type) bool {
- if len(xargs) != len(yargs) {
+ if !slices.EqualFunc(xargs, yargs, Identical) {
return false
}
- for i, xa := range xargs {
- if !Identical(xa, yargs[i]) {
- return false
- }
- }
-
return Identical(xorig, yorig)
}
import (
"cmd/compile/internal/syntax"
+ "cmp"
"fmt"
"go/constant"
. "internal/types/errors"
- "sort"
+ "slices"
"strconv"
"strings"
"unicode"
objList[i] = obj
i++
}
- sort.Sort(inSourceOrder(objList))
+ slices.SortFunc(objList, func(a, b Object) int {
+ return cmp.Compare(a.order(), b.order())
+ })
// add new methods to already type-checked types (from a prior Checker.Files call)
for _, obj := range objList {
check.methods = nil
}
-// inSourceOrder implements the sort.Sort interface.
-// TODO(gri) replace with slices.SortFunc
-type inSourceOrder []Object
-
-func (a inSourceOrder) Len() int { return len(a) }
-func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() }
-func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
// unusedImports checks for unused imports.
func (check *Checker) unusedImports() {
// If function bodies are not checked, packages' uses are likely missing - don't check.
"cmd/compile/internal/syntax"
"fmt"
"internal/testenv"
- "sort"
+ "slices"
"testing"
. "cmd/compile/internal/types2"
}
// 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 {
t.Errorf("simultaneous uses/defs = %s, want %s", got, want)
}
"cmd/compile/internal/syntax"
"fmt"
"io"
- "sort"
+ "slices"
"strings"
"sync"
)
names[i] = name
i++
}
- sort.Strings(names)
+ slices.Sort(names)
return names
}
import (
"cmd/compile/internal/syntax"
. "internal/types/errors"
- "sort"
+ "slices"
"strings"
)
return terms, comp
}
+func compareFunc(a, b *Func) int {
+ return a.cmp(&b.object)
+}
+
func sortMethods(list []*Func) {
- sort.Sort(byUniqueMethodName(list))
+ slices.SortFunc(list, compareFunc)
}
func assertSortedMethods(list []*Func) {
if !debug {
panic("assertSortedMethods called outside debug mode")
}
- if !sort.IsSorted(byUniqueMethodName(list)) {
+ if !slices.IsSortedFunc(list, compareFunc) {
panic("methods not sorted")
}
}
-// byUniqueMethodName method lists can be sorted by their unique method names.
-// todo: replace with slices.SortFunc
-type byUniqueMethodName []*Func
-
-func (a byUniqueMethodName) Len() int { return len(a) }
-func (a byUniqueMethodName) Less(i, j int) bool { return a[i].less(&a[j].object) }
-func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
// invalidTypeSet is a singleton type set to signal an invalid type set
// due to an error. It's also a valid empty type set, so consumers of
// type sets may choose to ignore it.
import (
"bytes"
"fmt"
- "sort"
+ "slices"
"strconv"
"strings"
"unicode/utf8"
w.error("unnamed type parameter")
break
}
- if i := tparamIndex(w.tparams.list(), t); i >= 0 {
+ if i := slices.Index(w.tparams.list(), t); i >= 0 {
// The names of type parameters that are declared by the type being
// hashed are not part of the type identity. Replace them with a
// placeholder indicating their index.
newTypeHasher(&buf, w.ctxt).typ(term.typ)
termHashes = append(termHashes, buf.String())
}
- sort.Strings(termHashes)
+ slices.Sort(termHashes)
if !first {
w.byte(';')
}
// look for matching scope description
desc := kind + ":" + strings.Join(scope.Names(), " ")
- found := false
- for _, d := range test.scopes {
- if desc == d {
- found = true
- break
- }
- }
- if !found {
+ if !slices.Contains(test.scopes, desc) {
t.Errorf("package %s: no matching scope found for %s", name, desc)
}
}
t.Errorf("%s: got object = %v; want none", test.src, f)
}
}
- if !sameSlice(index, test.index) {
+ if !slices.Equal(index, test.index) {
t.Errorf("%s: got index = %v; want %v", test.src, index, test.index)
}
if indirect != test.indirect {
_, _, _ = LookupFieldOrMethod(T, false, pkg, "M") // verify that LookupFieldOrMethod terminates
}
-func sameSlice(a, b []int) bool {
- if len(a) != len(b) {
- return false
- }
- for i, x := range a {
- if x != b[i] {
- return false
- }
- }
- return true
-}
-
// newDefined creates a new defined type named T with the given underlying type.
// Helper function for use with TestIncompleteInterfaces only.
func newDefined(underlying Type) *Named {
"go/token"
"internal/buildcfg"
. "internal/types/errors"
+ "slices"
)
func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
if debug {
// obj must be one of lhs
- found := false
- for _, lhs := range lhs {
- if obj == lhs {
- found = true
- break
- }
- }
- if !found {
+ if !slices.Contains(lhs, obj) {
panic("inconsistent lhs")
}
}
import (
"fmt"
"go/token"
+ "slices"
"strings"
)
// be able to use it either.
if check.conf.Error != nil {
defer func() {
- assert(inferred == nil || len(inferred) == len(tparams) && !containsNil(inferred))
+ assert(inferred == nil || len(inferred) == len(tparams) && !slices.Contains(inferred, nil))
}()
}
assert(params.Len() == len(args))
// If we already have all type arguments, we're done.
- if len(targs) == n && !containsNil(targs) {
+ if len(targs) == n && !slices.Contains(targs, nil) {
return targs
}
return
}
-// containsNil reports whether list contains a nil entry.
-func containsNil(list []Type) bool {
- for _, t := range list {
- if t == nil {
- return true
- }
- }
- return false
-}
-
// renameTParams renames the type parameters in the given type such that each type
// parameter is given a new identity. renameTParams returns the new type parameters
// and updated type. If the result type is unchanged from the argument type, none
}
case *TypeParam:
- return tparamIndex(w.tparams, t) >= 0
+ return slices.Index(w.tparams, t) >= 0
default:
panic(fmt.Sprintf("unexpected %T", typ))
// in w.tparams, iterative substitution will lead to infinite expansion.
// Nil out the corresponding type which effectively kills the cycle.
if tpar, _ := typ.(*TypeParam); tpar != nil {
- if i := tparamIndex(w.tparams, tpar); i >= 0 {
+ if i := slices.Index(w.tparams, tpar); i >= 0 {
// cycle through tpar
w.inferred[i] = nil
}
}
case *TypeParam:
- if i := tparamIndex(w.tparams, t); i >= 0 && w.inferred[i] != nil {
+ if i := slices.Index(w.tparams, t); i >= 0 && w.inferred[i] != nil {
w.typ(w.inferred[i])
}
w.typ(v.typ)
}
}
-
-// If tpar is a type parameter in list, tparamIndex returns the index
-// of the type parameter in list. Otherwise the result is < 0.
-func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
- for i, p := range list {
- if p == tpar {
- return i
- }
- }
- return -1
-}
"go/ast"
"go/token"
. "internal/types/errors"
+ "slices"
)
// labels checks correct label use in body.
}
jumpsOverVarDecl := func(jmp *ast.BranchStmt) bool {
- if varDeclPos.IsValid() {
- for _, bad := range badJumps {
- if jmp == bad {
- return true
- }
- }
- }
- return false
+ return varDeclPos.IsValid() && slices.Contains(badJumps, jmp)
}
blockBranches := func(lstmt *ast.LabeledStmt, list []ast.Stmt) {
package types_test
import (
+ "slices"
"strings"
"testing"
if got, want := sel.Obj().Name(), m.name; got != want {
t.Errorf("%s [method %d]: got name = %q at, want %q", src, i, got, want)
}
- if got, want := sel.Index(), m.index; !sameSlice(got, want) {
+ if got, want := sel.Index(), m.index; !slices.Equal(got, want) {
t.Errorf("%s [method %d]: got index = %v, want %v", src, i, got, want)
}
if got, want := sel.Indirect(), m.indirect; got != want {
return samePkg(obj.pkg, pkg)
}
-// less reports whether object a is ordered before object b.
+// cmp reports whether object a is ordered before object b.
+// cmp returns:
+//
+// -1 if a is before b
+// 0 if a is equivalent to b
+// +1 if a is behind b
//
// Objects are ordered nil before non-nil, exported before
// non-exported, then by name, and finally (for non-exported
// functions) by package path.
-func (a *object) less(b *object) bool {
+func (a *object) cmp(b *object) int {
if a == b {
- return false
+ return 0
}
// Nil before non-nil.
if a == nil {
- return true
+ return -1
}
if b == nil {
- return false
+ return +1
}
// Exported functions before non-exported.
ea := isExported(a.name)
eb := isExported(b.name)
if ea != eb {
- return ea
+ if ea {
+ return -1
+ }
+ return +1
}
// Order by name and then (for non-exported names) by package.
if a.name != b.name {
- return a.name < b.name
+ return strings.Compare(a.name, b.name)
}
if !ea {
- return a.pkg.path < b.pkg.path
+ return strings.Compare(a.pkg.path, b.pkg.path)
}
- return false
+ return 0
}
// A PkgName represents an imported Go package.
package types
-import "unicode"
+import (
+ "slices"
+ "unicode"
+)
// isValid reports whether t is a valid type.
func isValid(t Type) bool { return Unalias(t) != Typ[Invalid] }
// Instantiations are identical if their origin and type arguments are
// identical.
func identicalInstance(xorig Type, xargs []Type, yorig Type, yargs []Type) bool {
- if len(xargs) != len(yargs) {
+ if !slices.EqualFunc(xargs, yargs, Identical) {
return false
}
- for i, xa := range xargs {
- if !Identical(xa, yargs[i]) {
- return false
- }
- }
-
return Identical(xorig, yorig)
}
package types
import (
+ "cmp"
"fmt"
"go/ast"
"go/constant"
"go/internal/typeparams"
"go/token"
. "internal/types/errors"
- "sort"
+ "slices"
"strconv"
"strings"
"unicode"
objList[i] = obj
i++
}
- sort.Sort(inSourceOrder(objList))
+ slices.SortFunc(objList, func(a, b Object) int {
+ return cmp.Compare(a.order(), b.order())
+ })
// add new methods to already type-checked types (from a prior Checker.Files call)
for _, obj := range objList {
check.methods = nil
}
-// inSourceOrder implements the sort.Sort interface.
-// TODO(gri) replace with slices.SortFunc
-type inSourceOrder []Object
-
-func (a inSourceOrder) Len() int { return len(a) }
-func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() }
-func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
// unusedImports checks for unused imports.
func (check *Checker) unusedImports() {
// If function bodies are not checked, packages' uses are likely missing - don't check.
"fmt"
"go/token"
"io"
- "sort"
+ "slices"
"strings"
"sync"
)
names[i] = name
i++
}
- sort.Strings(names)
+ slices.Sort(names)
return names
}
import (
"go/token"
. "internal/types/errors"
- "sort"
+ "slices"
"strings"
)
return terms, comp
}
+func compareFunc(a, b *Func) int {
+ return a.cmp(&b.object)
+}
+
func sortMethods(list []*Func) {
- sort.Sort(byUniqueMethodName(list))
+ slices.SortFunc(list, compareFunc)
}
func assertSortedMethods(list []*Func) {
if !debug {
panic("assertSortedMethods called outside debug mode")
}
- if !sort.IsSorted(byUniqueMethodName(list)) {
+ if !slices.IsSortedFunc(list, compareFunc) {
panic("methods not sorted")
}
}
-// byUniqueMethodName method lists can be sorted by their unique method names.
-// todo: replace with slices.SortFunc
-type byUniqueMethodName []*Func
-
-func (a byUniqueMethodName) Len() int { return len(a) }
-func (a byUniqueMethodName) Less(i, j int) bool { return a[i].less(&a[j].object) }
-func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
// invalidTypeSet is a singleton type set to signal an invalid type set
// due to an error. It's also a valid empty type set, so consumers of
// type sets may choose to ignore it.
import (
"bytes"
"fmt"
- "sort"
+ "slices"
"strconv"
"strings"
"unicode/utf8"
w.error("unnamed type parameter")
break
}
- if i := tparamIndex(w.tparams.list(), t); i >= 0 {
+ if i := slices.Index(w.tparams.list(), t); i >= 0 {
// The names of type parameters that are declared by the type being
// hashed are not part of the type identity. Replace them with a
// placeholder indicating their index.
newTypeHasher(&buf, w.ctxt).typ(term.typ)
termHashes = append(termHashes, buf.String())
}
- sort.Strings(termHashes)
+ slices.Sort(termHashes)
if !first {
w.byte(';')
}