-
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 use tilde for struct type in type parameter #52295
Comments
|
I don't know what is the correct understanding for this. Your example seems align with your provided interpretation. The following example is also confusing because it feels like it is impossible to limit the type parameters to a slice that its element's "underlying" type is package main
type Type struct{}
type MyType Type
func main() {
x := []Type{}
y := []MyType{}
F1(x) // OK
F1(y) // ERROR: MyType does not implement Type
F2(y) // ERROR: cannot implement ~Type (empty type set)
F3(y) // ERROR: MyType does not implement interface{struct{}} (possibly missing ~ for struct{} in constraint interface{struct{}})
}
func F1[S []Elem, Elem Type](t S) {}
func F2[S []Elem, Elem ~Type](t S) {} // ERROR: invalid use of ~ (underlying type of Type is struct{})
func F3[S []Elem, Elem interface{ struct{} }](t S) {} |
Yeah, same issue. It is impossible because there is no type whose underlying type is
|
OK the trick is to use ~ in struct{}: func F4[S []Elem, Elem interface{ ~struct{} }](t S) {}
F4(y) // OK But what if it is a struct that we can't easily write? Does that mean we must provide and declare the nested struct in the type parameter? What if it is a circular struct? func F5[S []Elem, Elem ~struct { /* Next *CircularType??? */ ](t S) {}
type CircularType struct {
Next *CircularType
}
F5([]CircularType{}) Edit: What if there is a field typed in an unexported type? |
I think I don't know what to do with unexported fields. Do you have a real use case that you need to define the element type with a different name? (i.e. use |
I don't know how to answer what could be a real use case, but I am trying to write code like this: A polygon mesh structure that consists of a slice of polygons: type PolygonMesh struct { Faces []Polygon }
type Polygon struct {
verts []Vertex
....
} A specialized polygon, triangle, or quad has some sort of specialized implementation for polygons, such as computing normals, etc. type Triangle Polygon
func (t Triangle) Normal() Vec3 { /* ... do stuff with vertices */ }
type Quad Polygon
... more specialized methods ... There are also specialized polygon mesh structures: type TriangleMesh struct { Faces []Triangles }
type QuadMesh struct { Faces []Quad } Now, I am expecting an iterator over all faces: package mesh
func IterateFaces[F []Elem, Elem ~Polygon](faces F) { ... } So that on the caller side: mesh.IterateFaces(TriangleMesh{}.Faces)
mesh.IterateFaces(QuadMesh{}.Faces)
mesh.IterateFaces(PolygonMesh{}.Faces) |
Thanks. Would it be possible to define If you believe there is a missing feature and it is useful to add the support, you are welcome to file a proposal (or modify this issue to a proposal) to change the language spec. (With the current spec, I think the compiler is correct.) Thanks. |
I don't think it is possible to define as an alias because I don't have an idea about what a proposal could be. Sigh for this confusion. |
Another possible workaround would be, instead of defining Triangle etc. as I guess one idea that you could potentially proposing is to change the type set |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
https://go.dev/play/p/ugNI3jmBrjG
What did you expect to see?
Compile success
What did you see instead?
I am not sure if this was discussed somewhere, but I could not quickly find a discussion about this. This is the closest: https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#approximation-constraint-element that discusses the requirements for a constraint to be valid.
According to the spec:
Tilde "~" can be used to a
StructType
. The defined functionfunc F[T ~Type](t T)
is essentially
func F[T interface{~Type}](t T)
, and the type constraintsinterface{~Type}
is valid because its core type isType
.It is also confusing for this error message:
Not entirely clear to me: why
Type
does not implement~Type
? why is it an empty type set?The text was updated successfully, but these errors were encountered: