Skip to content

Commit 04617ea

Browse files
committed
go/types, types2: ensure that the reportCycle has a deterministic output
Fixes #71254
1 parent 6da1601 commit 04617ea

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,23 @@ 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+
if _, found := objMap[from].deps[to]; found {
143+
return []Object{to}
144+
}
145+
146+
// findPath is only called in cases where a cycle is indicated,
147+
// so performance is not critical.
148+
// Sort `deps` here in order to return a deterministic path,
149+
// thereby guaranteeing consistent output in the `reportCycle`.
150+
deps := make([]Object, 0, len(objMap[from].deps))
151+
for dep := range objMap[from].deps {
152+
deps = append(deps, dep)
153+
}
154+
slices.SortFunc(deps, func(x, y Object) int {
155+
return cmp.Compare(x.order(), y.order())
156+
})
157+
158+
for _, d := range deps {
146159
if P := findPath(objMap, d, to, seen); P != nil {
147160
return append(P, d)
148161
}

src/go/types/initorder.go

Lines changed: 17 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)