diff options
| author | Matthew Dempsky <mdempsky@google.com> | 2022-08-05 20:17:28 -0700 |
|---|---|---|
| committer | Matthew Dempsky <mdempsky@google.com> | 2022-08-09 16:42:21 +0000 |
| commit | 7d70779db5893a4ac1c4746f463b5aa0b4d7e527 (patch) | |
| tree | e9b1aeff85a329f895de407c34854c425b6167f1 /src/cmd/compile/internal/noder | |
| parent | 60d3276a944c3a6a65a8e462bc432d1e9cb040ee (diff) | |
| download | go-7d70779db5893a4ac1c4746f463b5aa0b4d7e527.tar.xz | |
cmd/compile/internal/noder: shuffle defined type handling code
Per TODO, this CL just moves code around without behavioral
change. Part of a cleanup process so that it's easier to access object
dictionaries where needed.
Change-Id: I95bb3cdd3cdb46cae47d76d5c1d5d8256661f222
Reviewed-on: https://go-review.googlesource.com/c/go/+/421816
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Diffstat (limited to 'src/cmd/compile/internal/noder')
| -rw-r--r-- | src/cmd/compile/internal/noder/writer.go | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index deee2887e2..5ef50ef71e 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -428,16 +428,16 @@ func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo { } case *types2.Named: - assert(typ.TypeParams().Len() == typ.TypeArgs().Len()) + obj, targs := splitNamed(typ) - // TODO(mdempsky): Why do we need to loop here? - orig := typ - for orig.TypeArgs() != nil { - orig = orig.Origin() + // Defined types that are declared within a generic function (and + // thus have implicit type parameters) are always derived types. + if w.p.hasImplicitTypeParams(obj) { + w.derived = true } w.Code(pkgbits.TypeNamed) - w.obj(orig.Obj(), typ.TypeArgs()) + w.obj(obj, targs) case *types2.TypeParam: index := func() int { @@ -617,16 +617,6 @@ func (w *writer) obj(obj types2.Object, explicits *types2.TypeList) { return } - // TODO(mdempsky): Push up into typIdx; this shouldn't be needed - // except while writing out types. - if isDefinedType(obj) && obj.Pkg() == w.p.curpkg { - decl, ok := w.p.typDecls[obj.(*types2.TypeName)] - assert(ok) - if len(decl.implicits) != 0 { - w.derived = true - } - } - w.Sync(pkgbits.SyncObject) w.Bool(false) w.Reloc(pkgbits.RelocObj, info.idx) @@ -2329,6 +2319,20 @@ func (w *writer) pkgObjs(names ...*syntax.Name) { // @@@ Helpers +// hasImplicitTypeParams reports whether obj is a defined type with +// implicit type parameters (e.g., declared within a generic function +// or method). +func (p *pkgWriter) hasImplicitTypeParams(obj *types2.TypeName) bool { + if obj.Pkg() == p.curpkg { + decl, ok := p.typDecls[obj] + assert(ok) + if len(decl.implicits) != 0 { + return true + } + } + return false +} + // isDefinedType reports whether obj is a defined type. func isDefinedType(obj types2.Object) bool { if obj, ok := obj.(*types2.TypeName); ok { @@ -2459,6 +2463,18 @@ func objTypeParams(obj types2.Object) *types2.TypeParamList { return nil } +// splitNamed decomposes a use of a defined type into its original +// type definition and the type arguments used to instantiate it. +func splitNamed(typ *types2.Named) (*types2.TypeName, *types2.TypeList) { + base.Assertf(typ.TypeParams().Len() == typ.TypeArgs().Len(), "use of uninstantiated type: %v", typ) + + orig := typ.Origin() + base.Assertf(orig.TypeArgs() == nil, "origin %v of %v has type arguments", orig, typ) + base.Assertf(typ.Obj() == orig.Obj(), "%v has object %v, but %v has object %v", typ, typ.Obj(), orig, orig.Obj()) + + return typ.Obj(), typ.TypeArgs() +} + func asPragmaFlag(p syntax.Pragma) ir.PragmaFlag { if p == nil { return 0 |
