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
spec: add examples (or more explicit prose) regarding the identity/difference of types escaping generic and non-generic functions #65152
Comments
cc @griesemer |
That's a very good question. I even think, perhaps erroneously, that the case I'm not sure I've read that right but the scoping rules around type declaration seem to speak in term of visibility not equality. As far as I remember, named type equality is still the equality of the name (identifier), type definition literal, and package path. But it might have changed. https://go.dev/ref/spec#Declarations_and_scope Just a remark, I have no answer. |
https://go.dev/ref/spec#Instantiations mentions, "instantiating a function produces a new non-generic function." So, every unique instantiation of I believe this is the fallacy in your argument:
It is not solely the AST, i.e. the syntactic location, which determines type identity. All type parameters which dominate the type definition participate as well. |
@zephyrtronium Ah, that actually makes sense, thank you. The behavior for non-used type parameters feels counterintuitive to me, but I guess it does follow from the spec and at least now I know :) I'll close this. |
So it's the named types having the slightly surprising behavior -- if you use unnamed types, these two are now identical. |
Yup, after rereading, seems that type names (identifiers) are unique and scoped, that's why named types are all different as per the spec. And the type definition includes the list of type arguments indeed but for x, there was none anyway so it doesn't even matter here. |
Reopening this (with title change) as a documentation issue. Similar questions have come up repeatedly and the spec could probably benefit from more explicit prose or related examples to be very clear. |
dup of #58573 |
Will this be documented as an unspecified behavior? |
This is implicitly specified because "each distinct instantiation of a generic function produces a distinct non-generic function; and each of those functions has its own distinct local types, very much like any other non-generic function". Leaving this one open as a documentation issue and closing #58573. |
What did you do?
Playground Link
What did you see happen?
true true true true
What did you expect to see?
true true true true
. The output is clearly intuitively correct and the most sensible behavior of this program. However, I'm having trouble justifying it from the spec.For equality of interfaces, the spec says:
The program is constructed such that the dynamic types all have exactly one dynamic value, hence we need to check if the dynamic types are identical:
In this case, all types involved are named types. So, the question is whether those named types are "other types" or not. Determining whether that is the case is the contention. The only relevant answer I can find says:
As well as later:
Lastly, going back to Type identity, we also note:
That's all the relevant spec pieces I can really find.
Now my argument:
F[int]() == F[int]()
andG() == G()
, demonstrating that the created type is not tied to a call, but to the type definition AST node.G() != F[int]()
demonstrates that different type definition AST nodes lead to non-identical types. Strengthening the assertion that the actual AST node determines type identity.Buf
F[int]() != F[string]()
shows that the same type definition can lead to different types. Even though 1. the type definition is not generic (it has no type parameters) and 2. it is a named type, so its identity should solely be determined by its type definition.To be clear, again: This is obviously the only sensible and expected way for this code to behave, but it seems there is a hole in the spec for this behavior.
The text was updated successfully, but these errors were encountered: