]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: use slices to simplify the code
authorapocelipes <seve3r@outlook.com>
Mon, 7 Oct 2024 15:24:17 +0000 (15:24 +0000)
committerGopher Robot <gobot@golang.org>
Mon, 7 Oct 2024 17:59:44 +0000 (17:59 +0000)
Simplify the code and remove some unnecessary helper functions.

Change-Id: I1419ca3a0c7048891bbdc274f53fd72960410651
GitHub-Last-Rev: 06b1f03bb36cf1028a52f0223af81cf74ec4d77c
GitHub-Pull-Request: golang/go#68732
Reviewed-on: https://go-review.googlesource.com/c/go/+/602719
Reviewed-by: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>

24 files changed:
src/cmd/compile/internal/types2/api_test.go
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/example_test.go
src/cmd/compile/internal/types2/infer.go
src/cmd/compile/internal/types2/issues_test.go
src/cmd/compile/internal/types2/labels.go
src/cmd/compile/internal/types2/object.go
src/cmd/compile/internal/types2/predicates.go
src/cmd/compile/internal/types2/resolver.go
src/cmd/compile/internal/types2/resolver_test.go
src/cmd/compile/internal/types2/scope.go
src/cmd/compile/internal/types2/typeset.go
src/cmd/compile/internal/types2/typestring.go
src/go/types/api_test.go
src/go/types/decl.go
src/go/types/infer.go
src/go/types/labels.go
src/go/types/methodset_test.go
src/go/types/object.go
src/go/types/predicates.go
src/go/types/resolver.go
src/go/types/scope.go
src/go/types/typeset.go
src/go/types/typestring.go

index 4024a3f7c812f8a9ed374fa9cf8e399e55b1b6c6..c43f33bcddcc0ce5de2b9ac4e7c21f7fbcebc094 100644 (file)
@@ -10,7 +10,7 @@ import (
        "fmt"
        "internal/goversion"
        "internal/testenv"
-       "sort"
+       "slices"
        "strings"
        "sync"
        "testing"
@@ -811,8 +811,8 @@ func sortedInstances(m map[*syntax.Name]Instance) (instances []recordedInstance)
        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
 }
@@ -1385,14 +1385,7 @@ func TestScopesInfo(t *testing.T) {
 
                        // 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)
                        }
                }
@@ -1942,7 +1935,7 @@ func TestLookupFieldOrMethod(t *testing.T) {
                                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 {
@@ -1979,18 +1972,6 @@ type Instance = *Tree[int]
        _, _, _ = 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)
index 3827e345633446c98a4e562808f630de3bdeb246..037155a6ca994ccec8d096ff486aabf4fcb0e783 100644 (file)
@@ -10,6 +10,7 @@ import (
        "go/constant"
        "internal/buildcfg"
        . "internal/types/errors"
+       "slices"
 )
 
 func (check *Checker) declare(scope *Scope, id *syntax.Name, obj Object, pos syntax.Pos) {
@@ -440,14 +441,7 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init syntax.Expr) {
 
        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")
                }
        }
index 7031fdb1ada63880e35a888e429b126024afaf0a..534d4cc01f103ecd3024825d5df8f0186aec15c4 100644 (file)
@@ -21,7 +21,7 @@ import (
        "fmt"
        "log"
        "regexp"
-       "sort"
+       "slices"
        "strings"
 )
 
@@ -141,14 +141,14 @@ func fib(x int) int {
        }
        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()
 
@@ -168,7 +168,7 @@ func fib(x int) int {
        //              mode(tv), tvstr)
        //      items = append(items, buf.String())
        // }
-       // sort.Strings(items)
+       // slices.Sort(items)
        // fmt.Println(strings.Join(items, "\n"))
 
        // Output:
index a57d25b2630e34c110f1d8c8ba696fbbfeac7dc1..350f46d34b82a37e973654bb9c91fa80c861c54c 100644 (file)
@@ -9,6 +9,7 @@ package types2
 import (
        "cmd/compile/internal/syntax"
        "fmt"
+       "slices"
        "strings"
 )
 
@@ -35,7 +36,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
        // 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))
                }()
        }
 
@@ -54,7 +55,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
        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
        }
 
@@ -457,16 +458,6 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
        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
@@ -636,7 +627,7 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
                }
 
        case *TypeParam:
-               return tparamIndex(w.tparams, t) >= 0
+               return slices.Index(w.tparams, t) >= 0
 
        default:
                panic(fmt.Sprintf("unexpected %T", typ))
@@ -717,7 +708,7 @@ func (w *cycleFinder) typ(typ Type) {
                // 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
                        }
@@ -786,7 +777,7 @@ func (w *cycleFinder) typ(typ Type) {
                }
 
        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])
                }
 
@@ -800,14 +791,3 @@ func (w *cycleFinder) varList(list []*Var) {
                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
-}
index 86b0a24e5195e8b7ea8a70a61d6f35bbe856b38c..57cb3b9257bbebf8dcf5ce7995e76f762f55ac26 100644 (file)
@@ -11,7 +11,7 @@ import (
        "fmt"
        "internal/testenv"
        "regexp"
-       "sort"
+       "slices"
        "strings"
        "testing"
 
@@ -164,7 +164,7 @@ L7 uses var z int`
                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 {
index 548df7925b101d5a7b2d719bb5e9225a93ec6cae..e44b7c7f70f3cd00ba2f306b68550c55f8329b15 100644 (file)
@@ -7,6 +7,7 @@ package types2
 import (
        "cmd/compile/internal/syntax"
        . "internal/types/errors"
+       "slices"
 )
 
 // labels checks correct label use in body.
@@ -108,14 +109,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.Lab
        }
 
        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)
index 627b8b307418dff4e851d4eeae1c6d65fde1572c..f968f652aac3802e3f11f0ca8e661765c678f8e9 100644 (file)
@@ -193,40 +193,48 @@ func (obj *object) sameId(pkg *Package, name string, foldCase bool) bool {
        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.
index ca51706d66c0e5c51e70a84d2b0de32744d363af..86b7e3dccf928d4325d7c1b63423f0b32e650300 100644 (file)
@@ -6,7 +6,10 @@
 
 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] }
@@ -506,16 +509,10 @@ func identicalOrigin(x, y *Named) bool {
 // 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)
 }
 
index f32835964826483c776bff3eb2389a59eb99b4fb..b2b3836e314d5f10e185b6cbc1986d081c31db4c 100644 (file)
@@ -6,10 +6,11 @@ package types2
 
 import (
        "cmd/compile/internal/syntax"
+       "cmp"
        "fmt"
        "go/constant"
        . "internal/types/errors"
-       "sort"
+       "slices"
        "strconv"
        "strings"
        "unicode"
@@ -682,7 +683,9 @@ func (check *Checker) packageObjects() {
                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 {
@@ -748,14 +751,6 @@ func (check *Checker) packageObjects() {
        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.
index 8105d8af42cdaef4aae001b9295ba9c460c8263e..daf4bb7a0134886b21ab42c53ae23b0d9042110e 100644 (file)
@@ -8,7 +8,7 @@ import (
        "cmd/compile/internal/syntax"
        "fmt"
        "internal/testenv"
-       "sort"
+       "slices"
        "testing"
 
        . "cmd/compile/internal/types2"
@@ -197,7 +197,7 @@ func TestResolveIdents(t *testing.T) {
        }
 
        // 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)
        }
index eefd8fac5b1376483967b06711edee0316d503d2..fc2a261ad6916a37ffe12784fae965be04b8f968 100644 (file)
@@ -10,7 +10,7 @@ import (
        "cmd/compile/internal/syntax"
        "fmt"
        "io"
-       "sort"
+       "slices"
        "strings"
        "sync"
 )
@@ -55,7 +55,7 @@ func (s *Scope) Names() []string {
                names[i] = name
                i++
        }
-       sort.Strings(names)
+       slices.Sort(names)
        return names
 }
 
index 8d2ca716147679b4f38a01d6de82a148b5153d39..e62c263b7dabe66f14d9a715d051249002b17192 100644 (file)
@@ -7,7 +7,7 @@ package types2
 import (
        "cmd/compile/internal/syntax"
        . "internal/types/errors"
-       "sort"
+       "slices"
        "strings"
 )
 
@@ -345,27 +345,23 @@ func intersectTermLists(xterms termlist, xcomp bool, yterms termlist, ycomp bool
        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.
index 36f90b673532f1aace1d2d2c69ca49349b37e066..47f53bc12d77b5589377cfc7543147d8f6e0da4e 100644 (file)
@@ -9,7 +9,7 @@ package types2
 import (
        "bytes"
        "fmt"
-       "sort"
+       "slices"
        "strconv"
        "strings"
        "unicode/utf8"
@@ -308,7 +308,7 @@ func (w *typeWriter) typ(typ Type) {
                        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.
@@ -382,7 +382,7 @@ func (w *typeWriter) typeSet(s *_TypeSet) {
                        newTypeHasher(&buf, w.ctxt).typ(term.typ)
                        termHashes = append(termHashes, buf.String())
                }
-               sort.Strings(termHashes)
+               slices.Sort(termHashes)
                if !first {
                        w.byte(';')
                }
index ac1fc63072d961b0cc11504d93c97a737d1a9cdf..b686578b38278aba48bb4dc391d963c2359bd0b6 100644 (file)
@@ -1386,14 +1386,7 @@ func TestScopesInfo(t *testing.T) {
 
                        // 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)
                        }
                }
@@ -1942,7 +1935,7 @@ func TestLookupFieldOrMethod(t *testing.T) {
                                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 {
@@ -1980,18 +1973,6 @@ type Instance = *Tree[int]
        _, _, _ = 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 {
index 9941dd538f199412d0e09e5776ed958619373ac9..4fd37df786de292c31a73a5d8e1735e078adf218 100644 (file)
@@ -11,6 +11,7 @@ import (
        "go/token"
        "internal/buildcfg"
        . "internal/types/errors"
+       "slices"
 )
 
 func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
@@ -515,14 +516,7 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
 
        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")
                }
        }
index 3bdbd798708075652cabf09d99605162a50124c8..ebb0a97c6393a8baa782780bfa088f5727ef9892 100644 (file)
@@ -12,6 +12,7 @@ package types
 import (
        "fmt"
        "go/token"
+       "slices"
        "strings"
 )
 
@@ -38,7 +39,7 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
        // 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))
                }()
        }
 
@@ -57,7 +58,7 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
        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
        }
 
@@ -460,16 +461,6 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
        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
@@ -639,7 +630,7 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
                }
 
        case *TypeParam:
-               return tparamIndex(w.tparams, t) >= 0
+               return slices.Index(w.tparams, t) >= 0
 
        default:
                panic(fmt.Sprintf("unexpected %T", typ))
@@ -720,7 +711,7 @@ func (w *cycleFinder) typ(typ Type) {
                // 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
                        }
@@ -789,7 +780,7 @@ func (w *cycleFinder) typ(typ Type) {
                }
 
        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])
                }
 
@@ -803,14 +794,3 @@ func (w *cycleFinder) varList(list []*Var) {
                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
-}
index 2f7f7bd20c0501fdb9ed63bcad2b836af889921e..97b753581aedd98026b15f4fa2944fe2c624c357 100644 (file)
@@ -8,6 +8,7 @@ import (
        "go/ast"
        "go/token"
        . "internal/types/errors"
+       "slices"
 )
 
 // labels checks correct label use in body.
@@ -109,14 +110,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele
        }
 
        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) {
index c40d05fc37b12e76b6ad549e07116a677c98dd50..37529fea4a985dfbb6987cb5b735f4a7fb7f326b 100644 (file)
@@ -5,6 +5,7 @@
 package types_test
 
 import (
+       "slices"
        "strings"
        "testing"
 
@@ -108,7 +109,7 @@ func TestNewMethodSet(t *testing.T) {
                        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 {
index 9cd18e30150a1ae54c78bdbfaaf6cb23b70677ed..80cd650ff154db6e77f25171b8838b2ff625c254 100644 (file)
@@ -196,40 +196,48 @@ func (obj *object) sameId(pkg *Package, name string, foldCase bool) bool {
        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.
index 017dc17c6a97961007e0187199a2931749a0f884..240c022848bf8a4a8c272e688496f9af096c9f92 100644 (file)
@@ -9,7 +9,10 @@
 
 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] }
@@ -509,16 +512,10 @@ func identicalOrigin(x, y *Named) bool {
 // 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)
 }
 
index 8cc57dc2dee24d9ab904a1836b7b0c4ac3da0f40..939bcecffa839a96074e38ceb2d20873b929ace8 100644 (file)
@@ -5,13 +5,14 @@
 package types
 
 import (
+       "cmp"
        "fmt"
        "go/ast"
        "go/constant"
        "go/internal/typeparams"
        "go/token"
        . "internal/types/errors"
-       "sort"
+       "slices"
        "strconv"
        "strings"
        "unicode"
@@ -678,7 +679,9 @@ func (check *Checker) packageObjects() {
                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 {
@@ -744,14 +747,6 @@ func (check *Checker) packageObjects() {
        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.
index 6d748009f8f431d5a2090e28d1c724262e1b9038..e3fb7b6effb06e3e0a1ecf45803eb42e741dd293 100644 (file)
@@ -13,7 +13,7 @@ import (
        "fmt"
        "go/token"
        "io"
-       "sort"
+       "slices"
        "strings"
        "sync"
 )
@@ -58,7 +58,7 @@ func (s *Scope) Names() []string {
                names[i] = name
                i++
        }
-       sort.Strings(names)
+       slices.Sort(names)
        return names
 }
 
index 84c713064639a89e2e791f15e69785cdd5ed5aaa..d04833863ddb9de6ac56946831f4f50564375be4 100644 (file)
@@ -10,7 +10,7 @@ package types
 import (
        "go/token"
        . "internal/types/errors"
-       "sort"
+       "slices"
        "strings"
 )
 
@@ -348,27 +348,23 @@ func intersectTermLists(xterms termlist, xcomp bool, yterms termlist, ycomp bool
        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.
index 3d6768db990e7f712e4db40cada40617e5f74a8e..804e80407ef52aa4bb4e3ef9a3d888cae3ebe594 100644 (file)
@@ -12,7 +12,7 @@ package types
 import (
        "bytes"
        "fmt"
-       "sort"
+       "slices"
        "strconv"
        "strings"
        "unicode/utf8"
@@ -311,7 +311,7 @@ func (w *typeWriter) typ(typ Type) {
                        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.
@@ -385,7 +385,7 @@ func (w *typeWriter) typeSet(s *_TypeSet) {
                        newTypeHasher(&buf, w.ctxt).typ(term.typ)
                        termHashes = append(termHashes, buf.String())
                }
-               sort.Strings(termHashes)
+               slices.Sort(termHashes)
                if !first {
                        w.byte(';')
                }