From 1f4d14e493516af6017ed9b467e7daf772752f98 Mon Sep 17 00:00:00 2001 From: Mark Freeman Date: Mon, 27 Oct 2025 16:37:16 -0400 Subject: [PATCH] go/types, types2: pull up package-level object sort to a separate phase This step allows future additional phases to reuse the sorted object list. Preparation for upcoming CLs. Change-Id: I22eaffd5bbe39c7cc101c6d860011dc3cb98ce37 Reviewed-on: https://go-review.googlesource.com/c/go/+/715480 Reviewed-by: Robert Griesemer LUCI-TryBot-Result: Go LUCI Auto-Submit: Mark Freeman --- src/cmd/compile/internal/types2/check.go | 10 ++++--- src/cmd/compile/internal/types2/resolver.go | 30 +++++++++++---------- src/go/types/check.go | 10 ++++--- src/go/types/resolver.go | 30 +++++++++++---------- 4 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/cmd/compile/internal/types2/check.go b/src/cmd/compile/internal/types2/check.go index 411a1719ce..8b27d9d3c1 100644 --- a/src/cmd/compile/internal/types2/check.go +++ b/src/cmd/compile/internal/types2/check.go @@ -141,9 +141,10 @@ type Checker struct { ctxt *Context // context for de-duplicating instances pkg *Package *Info - nextID uint64 // unique Id for type parameters (first valid Id is 1) - objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info - impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package + nextID uint64 // unique Id for type parameters (first valid Id is 1) + objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info + objList []Object // source-ordered keys of objMap + impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package // see TODO in validtype.go // valids instanceLookup // valid *Named (incl. instantiated) types per the validType check @@ -493,6 +494,9 @@ func (check *Checker) checkFiles(files []*syntax.File) { print("== collectObjects ==") check.collectObjects() + print("== sortObjects ==") + check.sortObjects() + print("== packageObjects ==") check.packageObjects() diff --git a/src/cmd/compile/internal/types2/resolver.go b/src/cmd/compile/internal/types2/resolver.go index 9d8769b96f..4c9eeb329c 100644 --- a/src/cmd/compile/internal/types2/resolver.go +++ b/src/cmd/compile/internal/types2/resolver.go @@ -508,6 +508,19 @@ func (check *Checker) collectObjects() { } } +// sortObjects sorts package-level objects by source-order for reproducible processing +func (check *Checker) sortObjects() { + check.objList = make([]Object, len(check.objMap)) + i := 0 + for obj := range check.objMap { + check.objList[i] = obj + i++ + } + slices.SortFunc(check.objList, func(a, b Object) int { + return cmp.Compare(a.order(), b.order()) + }) +} + // unpackRecv unpacks a receiver type expression and returns its components: ptr indicates // whether rtyp is a pointer receiver, base is the receiver base type expression stripped // of its type parameters (if any), and tparams are its type parameter names, if any. The @@ -626,19 +639,8 @@ func (check *Checker) resolveBaseTypeName(ptr bool, name *syntax.Name) (ptr_ boo // packageObjects typechecks all package objects, but not function bodies. func (check *Checker) packageObjects() { - // process package objects in source order for reproducible results - objList := make([]Object, len(check.objMap)) - i := 0 - for obj := range check.objMap { - objList[i] = obj - i++ - } - 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 { + for _, obj := range check.objList { if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil { check.collectMethods(obj) } @@ -661,7 +663,7 @@ func (check *Checker) packageObjects() { // its Type is Invalid. // // Investigate and reenable this branch. - for _, obj := range objList { + for _, obj := range check.objList { check.objDecl(obj, nil) } } else { @@ -673,7 +675,7 @@ func (check *Checker) packageObjects() { var aliasList []*TypeName var othersList []Object // everything that's not a type // phase 1: non-alias type declarations - for _, obj := range objList { + for _, obj := range check.objList { if tname, _ := obj.(*TypeName); tname != nil { if check.objMap[tname].tdecl.Alias { aliasList = append(aliasList, tname) diff --git a/src/go/types/check.go b/src/go/types/check.go index c9753280bf..d163012f1e 100644 --- a/src/go/types/check.go +++ b/src/go/types/check.go @@ -161,9 +161,10 @@ type Checker struct { fset *token.FileSet pkg *Package *Info - nextID uint64 // unique Id for type parameters (first valid Id is 1) - objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info - impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package + nextID uint64 // unique Id for type parameters (first valid Id is 1) + objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info + objList []Object // source-ordered keys of objMap + impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package // see TODO in validtype.go // valids instanceLookup // valid *Named (incl. instantiated) types per the validType check @@ -518,6 +519,9 @@ func (check *Checker) checkFiles(files []*ast.File) { print("== collectObjects ==") check.collectObjects() + print("== sortObjects ==") + check.sortObjects() + print("== packageObjects ==") check.packageObjects() diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go index dcf863b029..a8d11c2aa5 100644 --- a/src/go/types/resolver.go +++ b/src/go/types/resolver.go @@ -499,6 +499,19 @@ func (check *Checker) collectObjects() { } } +// sortObjects sorts package-level objects by source-order for reproducible processing +func (check *Checker) sortObjects() { + check.objList = make([]Object, len(check.objMap)) + i := 0 + for obj := range check.objMap { + check.objList[i] = obj + i++ + } + slices.SortFunc(check.objList, func(a, b Object) int { + return cmp.Compare(a.order(), b.order()) + }) +} + // unpackRecv unpacks a receiver type expression and returns its components: ptr indicates // whether rtyp is a pointer receiver, base is the receiver base type expression stripped // of its type parameters (if any), and tparams are its type parameter names, if any. The @@ -621,19 +634,8 @@ func (check *Checker) resolveBaseTypeName(ptr bool, name *ast.Ident) (ptr_ bool, // packageObjects typechecks all package objects, but not function bodies. func (check *Checker) packageObjects() { - // process package objects in source order for reproducible results - objList := make([]Object, len(check.objMap)) - i := 0 - for obj := range check.objMap { - objList[i] = obj - i++ - } - 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 { + for _, obj := range check.objList { if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil { check.collectMethods(obj) } @@ -656,7 +658,7 @@ func (check *Checker) packageObjects() { // its Type is Invalid. // // Investigate and reenable this branch. - for _, obj := range objList { + for _, obj := range check.objList { check.objDecl(obj, nil) } } else { @@ -668,7 +670,7 @@ func (check *Checker) packageObjects() { var aliasList []*TypeName var othersList []Object // everything that's not a type // phase 1: non-alias type declarations - for _, obj := range objList { + for _, obj := range check.objList { if tname, _ := obj.(*TypeName); tname != nil { if check.objMap[tname].tdecl.Assign.IsValid() { aliasList = append(aliasList, tname) -- 2.52.0