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,cmd/compile/internal/types2: inconsistent handling of len
on pointer-to-array type parameters
#47991
Comments
The "problem" here is that in |
With the latest decisions/implementation the status here is as follows. For: package p
func F[Ptr ~*Elem, Elem [1]int](p Ptr) int {
return len(p) // invalid
}
func G[Ptr ~*Elem, Elem [1]int | [2]int](p Ptr) int {
return len(*p)
}
func H[Ptr ~*Elem, Elem [1]int | [2]int](p Ptr) int {
return len(p) // invalid
} we get:
That is, implicit pointer-to-array dereferencing only happens if we have a pointer to an array (or a type parameter constrained by pointers to arrays, see below), not if we have a pointer to a type parameter. For comparison, this is valid at the moment: package p
func _[A *[0]int | [0]int | chan int](a A) {
_ = len(a)
} @ianlancetaylor any thoughts on the "correct" behavior? |
The current rules are:
This seems consistent with the generalization we apply to other operations on type parameters: an operation is permitted on a value of type parameter if it is permitted on all types in the type set of the type parameter @mdempsky Are you ok with this? If so, I am inclined to close this as working as intended at this point. |
I think this rule sounds reasonable; but my interpretation of it would be that F and H should both be valid, because Ptr's type set only contains pointer-to-array types and Am I missing something? If not, can you elaborate how you interpret that rule to disallow F and H? |
I'm taking the rules fairly literally: Type-set computation doesn't extend past the boundaries of an interface. Doing that would have all kinds of implications that we've not explored at all. So the type set of |
Okay, I see. Thanks for elaborating. I think rejecting both F and H is consistent and an improvement over the original behavior. I think it's the more conservative option too, so it makes sense to go with it at least for Go 1.18. I'm inclined to think type-set computation should extend recursively, to be analogous to how defined types work; e.g., |
Since the implementation of |
This package currently fails to typecheck in
H
:It's unclear to me the correct behavior here, but the current behavior at least seems inconsistent to me.
/cc @findleyr
The text was updated successfully, but these errors were encountered: