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: embedded field type cannot be a (pointer to a) type parameter #49030
Comments
The design doc says this should work: https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#embedded-type-parameter But we checked in a CL to forbid it: https://go-review.googlesource.com/c/go/+/337353 @Fullstop000 You can always name the field, as was done here: https://go-review.googlesource.com/c/go/+/337353/5/test/typeparam/lockable.go |
We tentatively concluded that embedding type parameters may not be permitted initially because of questions re: method promotion. The same questions arise with a pointer to a type parameter. But perhaps we can allow this after all. Will reconsider. |
We've talked about this again, and we're not going to change this for 1.18. Reasons:
func f[P constraint]() {
type S struct{
P // <<< should this be permitted?
}
...
}
The fact that the generics proposal still describes this possibility is simply an oversight. Eventually the spec (in progress) will be the final guiding document. Closing. Once we have gained more experience with type parameters we can reconsider this as a proposal. |
cc: @ianlancetaylor |
Sad it is not supported: type (
Number interface {
constraints.Integer | constraints.Float
}
IntFloat[T Number] struct {
// embedded field type cannot be a (pointer to a) type parameter
// https://github.com/golang/go/issues/49030
T
}
INumber interface {
Add(other INumber) INumber
Sub(other INumber) INumber
Mul(other INumber) INumber
Div(other INumber) INumber
Comp(other INumber) int
Eq(other INumber) bool
}
)
func (me IntFloat[T]) Add(other IntFloat[T]) IntFloat[T] {
return me.T + other.T
} |
To simplify this problem, it would be better to allow embedding any type names: #24062 |
Are there any plans for that today? |
@randall77 @griesemer I came across this when having a similar problem, but the suggestion you give does not allow items of generic type embedded as fields to have methods that allow the embedded field to be modified. When you name the field, you cannot have methods on that type with pointer receiver. This means that you cannot write the following (toy example):
Does not compile. ./prog.go:38:29: IntegerValue does not satisfy SomeValue (method FromString has pointer receiver). If we modify the code to make all of the methods have a non-pointer receiver, then
compiles, but:
Note that to get this to run without a segfault, I had to add this line:
So the field is indeed an interface which points to an implementation. If I omit this line, the program crashes with a segfault due to a null pointer exception. I can understand where embedding the type directly is disallowed, for the reasons given, however if using the type as a named field as "value SomeValue" above is the solution, what is the means to allow the embedded type to be modifiable with methods that have pointer receiver? I ask this because I indeed have cases where I can abstract functionality over a set of implementations in an orthogonal manner using this technique, except for the pointer-to-receiver issue. I would like the generic type ( Is this a compiler bug? As we can see above, |
Ah. LockableValue[*IntegerValue]. Sorry it did look like a compiler bug at first. Thanks. Sorry for complaining. |
repique does talk to the 'build system' and enjoyed the early relaxation FrozenDueToAge/release-blocker: golang/go#50731 golang/go#49030 golang/go#48334
What version of Go are you using (
go version
)?go version devel go1.18-cf51fb5d68 Sun Oct 17 04:27:13 2021 +0000 darwin/amd64
In https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md, the following code should be ok to be compiled:
What did you expect to see?
compile success
What did you see instead?
The text was updated successfully, but these errors were encountered: