Proposal Details
The go/types API exposes type parameters as a *TypeParamList. There is no exported mechanism to modify a TypeParamList. With generic methods, we sometimes want to view the receiver and method type parameters as a single type parameter list.
Motivation
One use case is in the noder, which merges receiver and method type arguments into a single set of explicit type arguments. It must first convert each list to a slice:
// asTypeParamSlice unpacks a types2.TypeParamList to a []types2.TypeParam
func asTypeParamSlice(l *types2.TypeParamList) []*types2.TypeParam {
if l.Len() == 0 {
return nil
}
s := make([]*types2.TypeParam, l.Len())
for i := range l.Len() {
s[i] = l.At(i)
}
return s
}
If the noder could create new type parameter lists, it wouldn't need to swap for a []*TypeParam.
Another example is go/ssa in x/tools. There, Function.TypeParams returns a TypeParamList. With generic methods, to uphold this API, we have to resort to an unsafe cast relying on the layout of TypeParamList:
func consTypeParamLists(l, r *types.TypeParamList) *types.TypeParamList {
tpars := make([]*types.TypeParam, l.Len()+r.Len())
for i := range l.Len() {
tpars[i] = l.At(i)
}
for i := range r.Len() {
tpars[i+l.Len()] = r.At(i)
}
return (*types.TypeParamList)(unsafe.Pointer(&tpars))
This isn't ideal. Note that the Function.TypeParams method will be deprecated in favor of methods which return either the receiver or method type parameters—not both.
Supposed API
I think all we need is a constructor, which is quite basic:
func NewTypeParamList(tparams ...*TypeParam) *TypeParamList {
return &TypeParamList{ tparams: tparams }
}
Proposal Details
The go/types API exposes type parameters as a
*TypeParamList. There is no exported mechanism to modify aTypeParamList. With generic methods, we sometimes want to view the receiver and method type parameters as a single type parameter list.Motivation
One use case is in the
noder, which merges receiver and method type arguments into a single set of explicit type arguments. It must first convert each list to a slice:If the
nodercould create new type parameter lists, it wouldn't need to swap for a[]*TypeParam.Another example is
go/ssainx/tools. There,Function.TypeParamsreturns aTypeParamList. With generic methods, to uphold this API, we have to resort to an unsafe cast relying on the layout ofTypeParamList:This isn't ideal. Note that the
Function.TypeParamsmethod will be deprecated in favor of methods which return either the receiver or method type parameters—not both.Supposed API
I think all we need is a constructor, which is quite basic: