Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/types: initialization cycle errors are non-deterministic #71254

Open
mateusz834 opened this issue Jan 13, 2025 · 6 comments · May be fixed by #71264
Open

go/types: initialization cycle errors are non-deterministic #71254

mateusz834 opened this issue Jan 13, 2025 · 6 comments · May be fixed by #71264
Assignees
Labels
BugReport Issues describing a possible bug in the Go implementation. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@mateusz834
Copy link
Member

Type-checking such code:

package p

const (
	B = A + B
	A = A + B
)

leads to non-deterministic errors, either:

initialization_cycle.go:4:2: no error expected: "initialization cycle for B"
initialization_cycle.go:5:2: no error expected: "initialization cycle: A refers to itself"
initialization_cycle.go:4:2: no error expected: "initialization cycle for B"
initialization_cycle.go:5:2: no error expected: "initialization cycle: A refers to itself"

or

initialization_cycle.go:4:2: no error expected: "initialization cycle for B"
initialization_cycle.go:5:2: no error expected: "initialization cycle: A refers to itself"
initialization_cycle.go:4:2: no error expected: "initialization cycle for B"
initialization_cycle.go:5:2: no error expected: "initialization cycle for A"

or

initialization_cycle.go:4:2: no error expected: "initialization cycle for B"
initialization_cycle.go:5:2: no error expected: "initialization cycle: A refers to itself"
initialization_cycle.go:4:2: no error expected: "initialization cycle: B refers to itself"
initialization_cycle.go:5:2: no error expected: "initialization cycle: A refers to itself"

It would be nice if go/types always returned the same error for the same input. I am not sure whether this is something that go/types should guarantee, feel free to close this issue, if that is fine.

CC @adonovan @griesemer

@mateusz834 mateusz834 added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 13, 2025
@adonovan
Copy link
Member

It would be nice if go/types always returned the same error for the same input. I am not sure whether this is something that go/types should guarantee.

We may not have written it down (and perhaps we should) but, I think all the go/types maintainers agree that it should be deterministic, even if it requires extra logic and computation to (e.g.) iterate over graphs in a particular order. This property is invaluable for debugging and well worth the effort.

@gabyhelp gabyhelp added the BugReport Issues describing a possible bug in the Go implementation. label Jan 13, 2025
@findleyr
Copy link
Member

I would go so far as to consider this a bug: type checking should be entirely deterministic.

@wingrez
Copy link
Contributor

wingrez commented Jan 14, 2025

// findPath returns the (reversed) list of objects []Object{to, ... from}
// such that there is a path of object dependencies from 'from' to 'to'.
// If there is no such path, the result is nil.
func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool) []Object {
	if seen[from] {
		return nil
	}
	seen[from] = true

	for d := range objMap[from].deps {
		if d == to {
			return []Object{d}
		}
		if P := findPath(objMap, d, to, seen); P != nil {
			return append(P, d)
		}
	}

	return nil
}

The problem is that the objMap[from].deps traversal in findPath is out of order, which leads to different results.
If that's acceptable, I would like to submit a patch.

@griesemer griesemer self-assigned this Jan 14, 2025
@griesemer
Copy link
Contributor

@wingrez Feel free to submit a CL for review; I expect this to be a very simple change. Thanks.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/642396 mentions this issue: types2: ensure that the reportCycle has a deterministic output

wingrez added a commit to wingrez/go that referenced this issue Jan 14, 2025
wingrez added a commit to wingrez/go that referenced this issue Jan 14, 2025
wingrez added a commit to wingrez/go that referenced this issue Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BugReport Issues describing a possible bug in the Go implementation. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants