-
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
proposal: spec: allow type conversion from generic type to same underlying type #61164
Comments
is the issue restricted to pointers? spec:
|
see: #50421 |
@seankhliao: As you pointed out, the conversion is allowed if the values are type parameter-typed.
This could allow pointers to type parameters, I think. |
By putting the pointer inside the type parameter, we can do a type conversion without a dynamic type conversion. See golang/go#61164 for context. Signed-off-by: Roger Peppe <rogpeppe@gmail.com> Change-Id: I0af66b474aaf840bddec933a89bc168843712674 Dispatch-Trailer: {"type":"trybot","CL":556442,"patchset":1,"ref":"refs/changes/42/556442/1","targetBranch":"master"}
This looks like a (small) language change. Perhaps it needs a proposal. cc @griesemer @ianlancetaylor @golang/compiler |
I agree that the spec doesn't currently permit this conversion. The spec says a conversion is permitted if, among other things:
There is no case that permits conversions of pointers to different type parameters. |
Agreed that the rules around conversions of pointer types involving type parameters could use some finessing. |
May I ask, if we do approve this, does it mean the following code would be allowed ? func tildeBaseCast[T any, E ~T](v E) T {
return T(v)
}
func tildBasePtrCast[T any, E ~T](v *E) *T {
return (*T)(v)
}
type IntAlias int
var ia IntAlias = 123
v1 := tildeBaseCast[int, IntAlias](ia) // type of v1 would be `int`
v2 := tildeBasePtrCast[int, IntAlias](&ia) // type of v2 would be `*int` |
Certainly not. This is a problem unrelated to type arguments. |
This would be very nice to have to allow you to "normalise" pointers, eliminating the need to keep track of the type parameter. Consider a type that writes to a pointer to e.g. a struct field: // this function can take a pointer to any field type
// whose underlying type is uint...
func NewUintIncrementer[T ~uint](dst *T) UintIncrementer {
return UintIncrementer{
Dst: (*uint)(dst), // currently doesn't work
}
}
// ...but this type doesn't need to know about the actual
// type of the field
type UintIncrementer struct {
Dst *uint
}
func (us UintIncrementer) Increment() {
*us.Dst += 1
} Right now, since the pointer conversion above doesn't work, you would have to make Since a conversion like Not sure if this union-less example warrants its own issue, since it might be easier to implement than the version in the OP? |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What did you do?
I compiled this code:
What did you expect to see?
Compilation success. We know that all of the possible types of
*T
can be converted to*A
so the conversion could be OK.What did you see instead?
To work around this, we can use a type switch: https://go.dev/play/p/PfuuWgA4eNG
But this is considerably more verbose and also more error-prone, because it fail at run time if one of the types in the type set isn't mentioned in the type switch.
The text was updated successfully, but these errors were encountered: