]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: add a NewSignatureType constructor accepting type parameters
authorRobert Findley <rfindley@google.com>
Mon, 27 Sep 2021 23:23:17 +0000 (19:23 -0400)
committerRobert Findley <rfindley@google.com>
Tue, 28 Sep 2021 15:20:51 +0000 (15:20 +0000)
In #47916, consensus has emerged that adding a new constructor is
preferable to using setters for type parameters. This is more consistent
with the rest of the type API, which is immutable except in cases where
mutation is necessary to break cycles (such as Named.SetUnderlying).

This CL adds a new constructor NewSignatureType that accepts type
parameters and receiver type parameters, deprecating the existing
NewSignature constructor. SetTypeParams and SetRecvTypeParams are not
yet removed: this will be done in a follow-up CL once x/tools no longer
has a dependency on the old APIs.

Updates #47916

Change-Id: I9d04dcfd304344d2aa08e527b371c3faa9d738e8
Reviewed-on: https://go-review.googlesource.com/c/go/+/352615
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/internal/gcimporter/iimport.go
src/go/types/signature.go

index f570aab2bfbc9b69ae6cbe44113aac97532c1be5..2a02c04ef34102e76b662cd4916d17524071455a 100644 (file)
@@ -304,8 +304,7 @@ func (r *importReader) obj(name string) {
                if tag == 'G' {
                        tparams = r.tparamList()
                }
-               sig := r.signature(nil)
-               sig.SetTypeParams(tparams)
+               sig := r.signature(nil, nil, tparams)
                r.declare(types.NewFunc(pos, r.currPkg, name, sig))
 
        case 'T', 'U':
@@ -329,19 +328,19 @@ func (r *importReader) obj(name string) {
                                mpos := r.pos()
                                mname := r.ident()
                                recv := r.param()
-                               msig := r.signature(recv)
 
                                // If the receiver has any targs, set those as the
                                // rparams of the method (since those are the
                                // typeparams being used in the method sig/body).
-                               targs := baseType(msig.Recv().Type()).TypeArgs()
+                               targs := baseType(recv.Type()).TypeArgs()
+                               var rparams []*types.TypeParam
                                if targs.Len() > 0 {
-                                       rparams := make([]*types.TypeParam, targs.Len())
+                                       rparams = make([]*types.TypeParam, targs.Len())
                                        for i := range rparams {
                                                rparams[i], _ = targs.At(i).(*types.TypeParam)
                                        }
-                                       msig.SetRecvTypeParams(rparams)
                                }
+                               msig := r.signature(recv, rparams, nil)
 
                                named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
                        }
@@ -576,7 +575,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
                return types.NewMap(r.typ(), r.typ())
        case signatureType:
                r.currPkg = r.pkg()
-               return r.signature(nil)
+               return r.signature(nil, nil, nil)
 
        case structType:
                r.currPkg = r.pkg()
@@ -616,7 +615,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
                                recv = types.NewVar(token.NoPos, r.currPkg, "", base)
                        }
 
-                       msig := r.signature(recv)
+                       msig := r.signature(recv, nil, nil)
                        methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
                }
 
@@ -673,11 +672,11 @@ func (r *importReader) kind() itag {
        return itag(r.uint64())
 }
 
-func (r *importReader) signature(recv *types.Var) *types.Signature {
+func (r *importReader) signature(recv *types.Var, rparams, tparams []*types.TypeParam) *types.Signature {
        params := r.paramList()
        results := r.paramList()
        variadic := params.Len() > 0 && r.bool()
-       return types.NewSignature(recv, params, results, variadic)
+       return types.NewSignatureType(recv, rparams, tparams, params, results, variadic)
 }
 
 func (r *importReader) tparamList() []*types.TypeParam {
index bf6c775b89b4592c1387ff221fa9a796de038219..df38e7124b98a137910da90e1db10adec945f556 100644 (file)
@@ -34,7 +34,18 @@ type Signature struct {
 // and results, either of which may be nil. If variadic is set, the function
 // is variadic, it must have at least one parameter, and the last parameter
 // must be of unnamed slice type.
+//
+// Deprecated: Use NewSignatureType instead which allows for type parameters.
 func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
+       return NewSignatureType(recv, nil, nil, params, results, variadic)
+}
+
+// NewSignatureType creates a new function type for the given receiver,
+// receiver type parameters, type parameters, parameters, and results. If
+// variadic is set, params must hold at least one parameter and the last
+// parameter must be of unnamed slice type. If recv is non-nil, typeParams must
+// be empty. If recvTypeParams is non-empty, recv must be non-nil.
+func NewSignatureType(recv *Var, recvTypeParams, typeParams []*TypeParam, params, results *Tuple, variadic bool) *Signature {
        if variadic {
                n := params.Len()
                if n == 0 {
@@ -44,7 +55,20 @@ func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
                        panic("variadic parameter must be of unnamed slice type")
                }
        }
-       return &Signature{recv: recv, params: params, results: results, variadic: variadic}
+       sig := &Signature{recv: recv, params: params, results: results, variadic: variadic}
+       if len(recvTypeParams) != 0 {
+               if recv == nil {
+                       panic("function with receiver type parameters must have a receiver")
+               }
+               sig.rparams = bindTParams(recvTypeParams)
+       }
+       if len(typeParams) != 0 {
+               if recv != nil {
+                       panic("function with type parameters cannot have a receiver")
+               }
+               sig.tparams = bindTParams(typeParams)
+       }
+       return sig
 }
 
 // Recv returns the receiver of signature s (if a method), or nil if a