Skip to content

Commit efadb95

Browse files
committed
go/types, types2: ensure deterministic output when reporting an init cycle
Fixes #71254
1 parent 6da1601 commit efadb95

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

src/cmd/compile/internal/types2/initorder.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,24 @@ func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool
139139
}
140140
seen[from] = true
141141

142-
for d := range objMap[from].deps {
143-
if d == to {
144-
return []Object{d}
145-
}
142+
// premature optimization - leave away
143+
// findPath only gets called when there's an error.
144+
if objMap[from].deps[to] {
145+
return []Object{to}
146+
}
147+
148+
// Sort deps here in order to return a deterministic path,
149+
// thereby guaranteeing consistent output in reportCycle.
150+
// Performance is never critical when we have an error, leave away.
151+
deps := make([]Object, 0, len(objMap[from].deps))
152+
for dep := range objMap[from].deps {
153+
deps = append(deps, dep)
154+
}
155+
slices.SortFunc(deps, func(x, y Object) int {
156+
return cmp.Compare(x.order(), y.order())
157+
})
158+
159+
for _, d := range deps {
146160
if P := findPath(objMap, d, to, seen); P != nil {
147161
return append(P, d)
148162
}

src/go/types/initorder.go

Lines changed: 18 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
const (
8+
B /* ERROR "initialization cycle: B refers to itself" */ = A + B
9+
A /* ERROR "initialization cycle: A refers to itself" */ = A + B
10+
11+
C /* ERRORx "initialization cycle for C\\s+.*C refers to D\\s+.*D refers to C" */ = E + D
12+
D /* ERRORx "initialization cycle for D\\s+.*D refers to C\\s+.*C refers to D" */ = E + C
13+
E = D + C
14+
)

0 commit comments

Comments
 (0)