-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: assignment rules need clarification when type parameters are involved #52628
Comments
In #45346 (comment), I suggested an alternative:
I still believe that that alternative would be more coherent than what is in the spec today. |
@bcmills The spec has special rules for assignability when type parameters are involved. The section on assignability says explicitly:
This section explicitly forbids the program you are mentioning and the implementation does the right thing. It may be that the section beforehand needs clearer prose to exclude this case which is handled later. But that's not the same as calling it an inconsistency. Retitled. With respect to whether the underlying type of a type parameter is its constraint interface: note that it is an interface with a "fixed" dynamic type, leading to separate rules. For instance, we cannot assign to them as if they were normal interfaces for exactly the reason you have pointed out above. But we can call their methods. We could type assert (if we were going to allow that), etc. There are fewer caveats ("special cases" as you call them) this way then if we define the underlying type of type parameters differently and then we always have to somehow refer to the type constraint of the type parameter to explain the functionality of the type parameter. As written, we can simply refer to a type parameter's type set (which is the type set of it's interface), the same way we refer to say the "element of slice S" rather than the "element of the underlying type of "S". In short, the current definition of the underlying type of a type parameter does add quite a bit of value, at least when it comes to the prose in the spec. It also explains various type parameter behavior for which we otherwise would have to invent some (possibly inconsistent) rules. |
Change https://go.dev/cl/405755 mentions this issue: |
The current spec says:
And (emphasis mine):
And:
And:
But, even worse:
If that last one actually held, then this program would be valid, but it clearly cannot be!
(https://go.dev/play/p/ofKOhQpJxgq)
So we see that nearly everywhere that the concept of “underlying types” is used, type parameters are either excluded entirely or treated differently — except for one place, where the fact that they aren't treated differently is an error in the spec.
That suggests to me that the definition of “underlying type” for type parameters is wrong: it doesn't provide any value in the actual uses of the concept of “underlying type” (since they all end up needing special cases to avoid it), and doesn't add consistency in and of itself.
(CC @griesemer, @ianlancetaylor, @mdempsky, @findleyr)
The text was updated successfully, but these errors were encountered: