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: guarantee that a finite number of distinct instances are reachable via the API #52728
Comments
My apologies, I meant to hit the "subscribe" button, not the "close" button! |
Just to add a bit more context: Laziness serves at least three purposes:
Of these:
|
With regard to point 3 it would be interesting to think about how many clients of the type-checker end up having to expand generic types, anyway. Since #52715 spawned this conversation, I'm also curious how the type-checker, which itself needs to know method sets, can avoid expanding types? |
Yes, this is a good point. I would guess that in some clients (such as gopls) most types get expanded anyway.
The type-checker expands types whenever necessary. It just so happens that the method set is not needed in the example in question: |
CC @timothy-king as well. The more I think about this, the more I think it was just a mistake not to guarantee that reachable types are always finite. Because of instantiation we can't guarantee that instances are canonical, but we can guarantee that they are finite. I think there's actually a way to achieve this lazily, without pinning the It occurred to me that we can do something similar during lazy expansion, even if we don't have a In other words, we introduce a new invariant. Exactly one of the following hold for a named type
As a result of this change, we would guarantee that any instance reachable from
In other words, each instance is expanded in a shared |
This seems like it could work. Worth a try. |
Change https://go.dev/cl/404885 mentions this issue: |
This seemed to work out well in the associated stack of CLs, but of course these sorts of changes require great care. It is possible that I will land this stack on Monday (within the parameters of the freeze grace period, since the stack was mailed before the freeze), but even if I don't I think this is a sufficiently severe problem that it warrants being made a release blocker for 1.19. I am not sure if it should be back-ported to 1.18, since the fix is not small and the problem with NewMethodSet and LookupFieldOrMethod has been avoided. |
In #52715, we see an example of unexpanded types escaping type-checking, that result in an infinite number of reachable types when interrogated via
Underlying
(though only a finite number of identical types).It would be nice if we could avoid such infinite expansion, as it is bound to cause problems for our users (see e.g. https://go.dev/cl/404335). One way to achieve this would be to provide wrappers for
Underlying
andMethod
that accept aContext
. Another option would be to enforce that unexpanded types do not escape the API, though this can result in a lot of unnecessary work when underlying types or instance methods are not needed.CC @griesemer @adonovan @mdempsky
The text was updated successfully, but these errors were encountered: