Similar to how we report initialization loops in initorder.go and type
alias loops in typecheck.go, this CL updates align.go to warn about
invalid recursive types. The code is based on the loop code from
initorder.go, with minimal changes to adapt from detecting
variable/function initialization loops to detecting type declaration
Thanks to Cuong Manh Le for investigating this, helping come up with
test cases, and exploring solutions.
Run-TryBot: Matthew Dempsky <firstname.lastname@example.org>
TryBot-Result: Go Bot <email@example.com>
Reviewed-by: Robert Griesemer <firstname.lastname@example.org>
Reviewed-by: Cuong Manh Le <email@example.com>
Trust: Matthew Dempsky <firstname.lastname@example.org>
Trust: Cuong Manh Le <email@example.com>
@griesemer Thanks for details explanation, I don't know that go/types also don't record alias name like cmd/compile. But my concern is that in go1.13.x, we does report alias name in the cycle. Is the behavior change intentional in go1.14.x and above?
https://golang.org/cl/259447 proposes one way to solve this: by preserving type alias information in the type graph until the last possible moment. This is achieved by introducing a typeAlias Type for internal use only, and 'collapsing' this type at API boundaries.
The other thing I tried was to preserve syntactic cycle information in, for example, a Checker.cycles map, so that we can accurately report all the edges in our cycle when it is later discovered to be invalid. This proved to be quite complex though, because it's not trivial to reverse-engineer the syntactic cycle that corresponds to a type cycle (consider the case where we have a deep, high degree graph of type aliases).
The downside of CL 259447 is that we have to be very careful not to leak the typeAlias type. There are some things we could do to make this safer, for example introducing a new type to mean "all Types plus aliases", but such a change would turn out to be quite large and I don't want to embark on this without discussing with @griesemer.