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
cmd/compile: the rule is too restricted when ranging over values of type parameters #49551
Comments
Sorry, the first function |
A problem is that I'm not quite sure why a two-index slice doesn't work, though. An index expression works. CC @griesemer @findleyr |
Please file a separate issue for the slice error and assign it to me. That's a simple oversight. The range behavior is expected. Closing this issue as working as intended. Thanks. |
Never mind, this is a tad tricky to get right. Filed #49566 so it doesn't get forgotten. |
This is not only for func ForEach[T []string|map[int]string](c T, f func(string)) {
// cannot range over s (variable of type T constrained by []byte|map[int]byte) (T has no structural type)
for _, v := range c {
f(v)
}
} Even the following way also doesn't work: func Max[T []E|map[int]E, E string](c T, f func(E)) {
// cannot range over s (variable of type T constrained by []byte|map[int]byte) (T has no structural type)
for _, v := range c {
f(v)
}
} |
If this is intended, I would like to submit a proposal to allow this. |
This is intended. Mixing maps and slices this way in a range loop may seem appealing but quite possibly not a good idea because the behavior is so different (for one, map iteration is randomized, slice iteration is always the same). But you're welcome to file a proposal. Thanks. |
Range doesn't work for even much simpler cases, such as arrays of the same element type but with different lengths: https://go.dev/play/p/Bz-XFdM-K8S?v=gotip This really feels like it should work, but doesn't: package main
import "fmt"
type multiArrayOfInt interface {
[1]int | [2]int | [3]int | [4]int
}
func arraySummer[A multiArrayOfInt](array A) (sum int) {
for _, v := range array {
sum += v
}
return
}
func main() {
fmt.Println(arraySummer([3]int{1, 2, 3}))
} Errors with: And it also doesn't work with only map types, even when only the keys types vary and are discarded by the range. https://go.dev/play/p/wMG2KIU2wo8?v=gotip
Duh, nevermind, for maps in this case you can just move the map type out of the interface constraint into the function parameter types. 😬 Still seems like the array case should work, but maybe it has something to do with the not being able to parameterize over constants (i.e. why the parameterized multiArrayOfInt type above is needed at all...) |
Presumably this could be made to work, but it's not clear why this (array) case is important. We will not change this for 1.18. We have the proposal process to change things like this in the future. Thanks. |
@griesemer Thanks for the explanation, that makes sense, and I'm glad to hear this restriction is being documented more thoroughly. Since parameterizing constants isn't in the current spec, I'm definitely using generic types with an enumerated list of short array types as in my example above. I need slices of arrays of uint64, where the arrays are relatively short (1, 2, 4, 8...) and the containing slice length is huge (billions). Using a slice of slices of uint64 in this case introduces unacceptable slice header overhead (and runtime bounds checking). Today I generate code for all of these different cases, so generics will eliminate a lot of that. I fought a very short battle to get parameterized integer constants into the spec, but quickly gave up when it became clear there was little interest in it. |
Note that allowing your array case to work with |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes, the latest tip.
What did you do?
What did you expect to see?
Compiles okay.
What did you see instead?
Some functions don't compile.
The rule is too restricted, which will limit the use scope of type parameters.
The text was updated successfully, but these errors were encountered: