go/types, types2: ensure deterministic output when reporting an init cycle

Fixes #71254

Change-Id: Ie3bad281403c8ff6215e03d92760b9a378714cee
GitHub-Last-Rev: 9b804a7842421dca6a97c57ce18523b593b0817d
GitHub-Pull-Request: golang/go#71264
Reviewed-on: https://go-review.googlesource.com/c/go/+/642396
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
This commit is contained in:
Wingrez 2025-01-17 00:38:59 +00:00 committed by Gopher Robot
parent 80bf7d83ed
commit 87023bb27f
3 changed files with 34 additions and 0 deletions

View file

@ -10,6 +10,7 @@ import (
"fmt"
. "internal/types/errors"
"slices"
"sort"
)
// initOrder computes the Info.InitOrder for package variables.
@ -139,7 +140,16 @@ func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool
}
seen[from] = true
// sort deps for deterministic result
var deps []Object
for d := range objMap[from].deps {
deps = append(deps, d)
}
sort.Slice(deps, func(i, j int) bool {
return deps[i].order() < deps[j].order()
})
for _, d := range deps {
if d == to {
return []Object{d}
}

View file

@ -0,0 +1,14 @@
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
const (
B /* ERROR "initialization cycle: B refers to itself" */ = A + B
A /* ERRORx "initialization cycle for A\\s+.*A refers to B\\s+.*B refers to A" */ = A + B
C /* ERRORx "initialization cycle for C\\s+.*C refers to D\\s+.*D refers to C" */ = E + D
D /* ERRORx "initialization cycle for D\\s+.*D refers to C\\s+.*C refers to D" */ = E + C
E = D + C
)

View file

@ -13,6 +13,7 @@ import (
"fmt"
. "internal/types/errors"
"slices"
"sort"
)
// initOrder computes the Info.InitOrder for package variables.
@ -142,7 +143,16 @@ func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool
}
seen[from] = true
// sort deps for deterministic result
var deps []Object
for d := range objMap[from].deps {
deps = append(deps, d)
}
sort.Slice(deps, func(i, j int) bool {
return deps[i].order() < deps[j].order()
})
for _, d := range deps {
if d == to {
return []Object{d}
}