]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/noder: shuffle defined type handling code
authorMatthew Dempsky <mdempsky@google.com>
Sat, 6 Aug 2022 03:17:28 +0000 (20:17 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 9 Aug 2022 16:42:21 +0000 (16:42 +0000)
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>
src/cmd/compile/internal/noder/writer.go

index deee2887e223c7dc225c99a32bce8e8b1d343fb4..5ef50ef71e69f29ebd5b757ac2ad0a6f2775f15e 100644 (file)
@@ -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