47e34ca533
During type-checking, newly created instances share a type checking Context which de-duplicates identical instances. However, when unexpanded types escape the type-checking pass or are created via calls to Instantiate, they lack this shared context. As reported in #52728, this may lead to infinitely many identical but distinct types that are reachable via the API. This CL introduces a new invariant that ensures we don't create such infinitely expanding chains: instances created during expansion share a context with the type that led to their creation. During expansion, the expanding type passes its Context to any newly created instances. This ensures that cycles will eventually terminate with a previously seen instance. For example, if we have an instantiation chain T1[P]->T2[P]->T3[P]->T1[P], by virtue of this Context passing the expansion of T3[P] will find the instantiation T1[P]. In general, storing a Context in a Named type could lead to pinning types in memory unnecessarily, but in this case the Context pins only those types that are reachable from the original instance. This seems like a reasonable compromise between lazy and eager expansion. Our treatment of Context was a little haphazard: Checker.bestContext made it easy to get a context at any point, but made it harder to reason about which context is being used. To fix this, replace bestContext with Checker.context, which returns the type-checking context and panics on a nil receiver. Update all call-sites to verify that the Checker is non-nil when context is called. Also make it a panic to call subst with a nil context. Instead, update subst to explicitly accept a local (=instance) context along with a global context, and require that one of them is non-nil. Thread this through to the call to Checker.instance, and handle context updating there. Fixes #52728 Change-Id: Ib7f26eb8c406290325bc3212fda25421a37a1e8e Reviewed-on: https://go-review.googlesource.com/c/go/+/404885 Reviewed-by: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Robert Findley <rfindley@google.com> |
||
---|---|---|
.github | ||
api | ||
doc | ||
lib/time | ||
misc | ||
src | ||
test | ||
.gitattributes | ||
.gitignore | ||
AUTHORS | ||
codereview.cfg | ||
CONTRIBUTING.md | ||
CONTRIBUTORS | ||
LICENSE | ||
PATENTS | ||
README.md | ||
SECURITY.md |
The Go Programming Language
Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.
Gopher image by Renee French, licensed under Creative Commons 3.0 Attributions license.
Our canonical Git repository is located at https://go.googlesource.com/go. There is a mirror of the repository at https://github.com/golang/go.
Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.
Download and Install
Binary Distributions
Official binary distributions are available at https://go.dev/dl/.
After downloading a binary release, visit https://go.dev/doc/install for installation instructions.
Install From Source
If a binary distribution is not available for your combination of operating system and architecture, visit https://go.dev/doc/install/source for source installation instructions.
Contributing
Go is the work of thousands of contributors. We appreciate your help!
To contribute, please read the contribution guidelines at https://go.dev/doc/contribute.
Note that the Go project uses the issue tracker for bug reports and proposals only. See https://go.dev/wiki/Questions for a list of places to ask questions about the Go language.