-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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: cannot index pointer to generic array #49447
Comments
I think this may be expected at present. |
This is currently as expected. Note that the existing rules in the spec require a pointer to an array. Expanding this to type parameters requires that we have pointers to arrays in the type parameter type set (which is accepted). We'd need a new rule to generalize this also across a type parameter boundary. I'm not saying we can't do that, but it's an exception to the otherwise relatively regular rules. This works: package p
type a1 [16]byte
type a2 [32]byte
type A interface {
*a1 | *a2
}
func elem0[T A](t T) *byte {
return &t[0]
} is that not sufficient? |
This is what I mentioned above about embedding an array in a generic struct to avoid extra indirections and allocs. (But maybe I'm missing something. I find I still do not yet know how to make good use of generics.) |
Can you show us more context? Show us the program that doesn't work with @griesemer 's suggestion. |
In the course of writing a minimized program, I found a workaround:
It's ugly, but it works. |
Just catching up and curious about this. @josharian why is that type switch necessary? Why can't you use @griesemer's suggestion of including the pointer-to-array types in the type parameter type set?
But also, @griesemer I'm not sure that supporting this would make the spec less regular, and supporting this seems straightforward (I have a CL that does it...). I actually think that @josharian demonstrated that it would be less surprising if this worked, than if it doesn't. |
I agree that supporting it is straight-forward. But we need an extra rule. We may also need to look into other situations where we may need to apply this (pointer-to-struct in some cases). |
Ok, thought about this a bit more. I think it may more generally be a source of confusion that type expressions do not 'map over' type sets; i.e. the type set of But I don't think anything needs to be done for 1.18. I'll re-close this issue again and we can revisit if there is further confusion of this sort. I would still be interested in @josharian's use-case though. |
The use case is a trie for looking up IP addresses (without zones). For space reasons, it'd be nice to have an IPv4 trie I was definitely using the mental heuristic you indicated. I also just encountered an identical issue with slicing: func asSlice[T A](t T) []byte {
return t[:]
} also does not compile, even though it compiles for each of the types in T. Here's a more complete program: package p
type a1 [16]byte
type a2 [32]byte
type A interface {
a1 | a2
}
type S[T A] struct {
arr T // initial backing array for buf
buf []byte
}
func makeT[T A]() *S[T] {
var s S[T]
switch a := any(s.arr).(type) {
case a1:
s.buf = a[:]
case a2:
s.buf = a[:]
default:
panic("unreachable")
}
return &s
} It'd be nice to be able to remove the dynamic type switch from Note that defining T as |
This does not compile:
Error:
./x.go:11:10: invalid operation: cannot index t (variable of type *T)
This shows up in practice if you want to embed an array in a generic struct to avoid extra indirection/allocs, like this:
but pass pointers to the array around internally to avoid making lots of copies of it (particularly as the array gets large).
The equivalent non-generic code compiles:
The text was updated successfully, but these errors were encountered: