diff options
| author | Mark Freeman <mark@golang.org> | 2026-04-01 15:37:39 -0400 |
|---|---|---|
| committer | Mark Freeman <mark@golang.org> | 2026-04-03 10:09:56 -0700 |
| commit | ae1edbeb2f77c8242ab7adf57b2449ae4740544d (patch) | |
| tree | 9749bce93a54f3eb24c99f3064806fd4528e8764 | |
| parent | 330aec810997f89262fa04939a00425194e94216 (diff) | |
| download | go-ae1edbeb2f77c8242ab7adf57b2449ae4740544d.tar.xz | |
cmd/compile/internal/noder: decode generic methods and pipe receivers
Change-Id: I7a66fba400a743f4ef2fb989cd8e74e955e22b0f
Reviewed-on: https://go-review.googlesource.com/c/go/+/762020
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Mark Freeman <markfreeman@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
| -rw-r--r-- | src/cmd/compile/internal/noder/reader.go | 38 | ||||
| -rw-r--r-- | src/cmd/compile/internal/noder/writer.go | 20 |
2 files changed, 47 insertions, 11 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index ebb5043a05..e0545a86db 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -784,14 +784,22 @@ func (pr *pkgReader) objIdxMayFail(idx index, implicits, explicits []*types.Type return name, nil case pkgbits.ObjFunc: - if sym.Name == "init" { - sym = Renameinit() - } - npos := r.pos() setBasePos(npos) + + var sel *types.Sym + var recv *types.Field + if r.Version().Has(pkgbits.GenericMethods) && r.Bool() { + sel = r.selector() + r.recvTypeParamNames() + recv = r.param() + } else { + if sym.Name == "init" { + sym = Renameinit() + } + } r.typeParamNames() - typ := r.signature(nil) + typ := r.signature(recv) fpos := r.pos() fn := ir.NewFunc(fpos, npos, sym, typ) @@ -819,7 +827,7 @@ func (pr *pkgReader) objIdxMayFail(idx index, implicits, explicits []*types.Type } } - rext.funcExt(name, nil) + rext.funcExt(name, sel) return name, nil case pkgbits.ObjType: @@ -1021,7 +1029,11 @@ func (pr *pkgReader) objDictIdx(sym *types.Sym, idx index, implicits, explicits } nimplicits := r.Len() - nexplicits := r.Len() + nreceivers := 0 + if r.Version().Has(pkgbits.GenericMethods) { + nreceivers = r.Len() + } + nexplicits := r.Len() + nreceivers if nimplicits > len(implicits) || nexplicits != len(explicits) { return nil, fmt.Errorf("%v has %v+%v params, but instantiated with %v+%v args", sym, nimplicits, nexplicits, len(implicits), len(explicits)) @@ -1029,6 +1041,7 @@ func (pr *pkgReader) objDictIdx(sym *types.Sym, idx index, implicits, explicits dict.targs = append(implicits[:nimplicits:nimplicits], explicits...) dict.implicits = nimplicits + dict.receivers = nreceivers // Within the compiler, we can just skip over the type parameters. for range dict.targs[dict.implicits:] { @@ -1095,10 +1108,19 @@ func (pr *pkgReader) objDictIdx(sym *types.Sym, idx index, implicits, explicits return &dict, nil } +func (r *reader) recvTypeParamNames() { + r.Sync(pkgbits.SyncTypeParamNames) + + for range r.dict.targs[r.dict.implicits : r.dict.implicits+r.dict.receivers] { + r.pos() + r.localIdent() + } +} + func (r *reader) typeParamNames() { r.Sync(pkgbits.SyncTypeParamNames) - for range r.dict.targs[r.dict.implicits:] { + for range r.dict.targs[r.dict.implicits+r.dict.receivers:] { r.pos() r.localIdent() } diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index a42b11f6fa..85686a481a 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -203,9 +203,10 @@ type writer struct { // A writerDict tracks types and objects that are used by a declaration. type writerDict struct { - // implicits is a slice of type parameters from the enclosing - // declarations. + // implicits contains type parameters from enclosing declarations. implicits []*types2.TypeParam + // receivers contains receiver type parameters of the declaration. + receivers []*types2.TypeParam // derived is a slice of type indices for computing derived types // (i.e., types that depend on the declaration's type parameters). @@ -934,11 +935,21 @@ func (w *writer) objDict(obj types2.Object, dict *writerDict) { // doesn't care about referenced functions. w.dict = dict // TODO(mdempsky): This is a bit sketchy. - w.Len(len(dict.implicits)) + rtparams := objRecvTypeParams(obj) tparams := objTypeParams(obj) + + if w.Version().Has(pkgbits.GenericMethods) { + w.Len(len(rtparams)) + } else { + assert(len(rtparams) == 0) + } w.Len(len(tparams)) + + for _, rtparam := range rtparams { + w.typ(rtparam.Constraint()) + } for _, tparam := range tparams { w.typ(tparam.Constraint()) } @@ -970,6 +981,9 @@ func (w *writer) objDict(obj types2.Object, dict *writerDict) { for _, implicit := range dict.implicits { w.Bool(implicit.Underlying().(*types2.Interface).IsMethodSet()) } + for _, rtparam := range rtparams { + w.Bool(rtparam.Underlying().(*types2.Interface).IsMethodSet()) + } for _, tparam := range tparams { w.Bool(tparam.Underlying().(*types2.Interface).IsMethodSet()) } |
