]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: add Named.SetTParams and Named.Orig methods
authorRob Findley <rfindley@google.com>
Thu, 3 Jun 2021 15:37:26 +0000 (11:37 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 7 Jun 2021 17:06:56 +0000 (17:06 +0000)
This is a port of CL 309832 to go/types, adjusted to not export the new
API and to amend TestSizeof.

Change-Id: I67efd3ba9b921c8431528eba1cd88ec1f41898bb
Reviewed-on: https://go-review.googlesource.com/c/go/+/324755
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/types/decl.go
src/go/types/sanitize.go
src/go/types/sizeof_test.go
src/go/types/subst.go
src/go/types/type.go

index 9211febc6da1620a43e9867af2f37c149a6f0753..12ee51b9201d8604429de4ffc3e7923460ff236b 100644 (file)
@@ -333,7 +333,7 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
                switch t.info {
                case unknown:
                        t.info = marked
-                       t.info = check.validType(t.orig, append(path, t.obj)) // only types of current package added to path
+                       t.info = check.validType(t.fromRHS, append(path, t.obj)) // only types of current package added to path
                case marked:
                        // cycle detected
                        for i, tn := range path {
@@ -692,9 +692,8 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
        } else {
                // defined type declaration
 
-               named := check.newNamed(obj, nil, nil)
+               named := check.newNamed(obj, nil, nil, nil, nil)
                def.setUnderlying(named)
-               obj.typ = named // make sure recursive type declarations terminate
 
                if tparams := typeparams.Get(tdecl); tparams != nil {
                        check.openScope(tdecl, "type parameters")
@@ -703,7 +702,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
                }
 
                // determine underlying type of named
-               named.orig = check.definedType(tdecl.Type, named)
+               named.fromRHS = check.definedType(tdecl.Type, named)
 
                // The underlying type of named may be itself a named type that is
                // incomplete:
@@ -718,7 +717,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
                // and which has as its underlying type the named type B.
                // Determine the (final, unnamed) underlying type by resolving
                // any forward chain.
-               // TODO(gri) Investigate if we can just use named.origin here
+               // TODO(gri) Investigate if we can just use named.fromRHS here
                //           and rely on lazy computation of the underlying type.
                named.underlying = under(named)
        }
index f167cdd8b63ae113d8a9910a9c90277b0667f3f6..88fc3f837726c0c0d5a45ebb3134926c84c6be60 100644 (file)
@@ -138,8 +138,8 @@ func (s sanitizer) typ(typ Type) Type {
                if debug && t.check != nil {
                        panic("internal error: Named.check != nil")
                }
-               if orig := s.typ(t.orig); orig != t.orig {
-                       t.orig = orig
+               if orig := s.typ(t.fromRHS); orig != t.fromRHS {
+                       t.fromRHS = orig
                }
                if under := s.typ(t.underlying); under != t.underlying {
                        t.underlying = under
index 5a9d07ca41802a9edbf292a9b0f0d738e86d268f..3af9079a85c965032234d1e97d22b328cee240ba 100644 (file)
@@ -30,7 +30,7 @@ func TestSizeof(t *testing.T) {
                {Interface{}, 60, 120},
                {Map{}, 16, 32},
                {Chan{}, 12, 24},
-               {Named{}, 64, 128},
+               {Named{}, 68, 136},
                {_TypeParam{}, 28, 48},
                {instance{}, 44, 88},
                {bottom{}, 0, 0},
index d27f3645cc3404e1a6a790c36dce1b30f73b288d..43a64d04bb5d100d088db88cbd29a96918f87db6 100644 (file)
@@ -396,8 +396,7 @@ func (subst *subster) typ(typ Type) Type {
 
                // create a new named type and populate caches to avoid endless recursion
                tname := NewTypeName(subst.pos, t.obj.pkg, t.obj.name, nil)
-               named := subst.check.newNamed(tname, t.underlying, t.methods) // method signatures are updated lazily
-               named.tparams = t.tparams                                     // new type is still parameterized
+               named := subst.check.newNamed(tname, t, t.underlying, t.tparams, t.methods) // method signatures are updated lazily
                named.targs = newTargs
                if subst.check != nil {
                        subst.check.typMap[h] = named
@@ -407,7 +406,7 @@ func (subst *subster) typ(typ Type) Type {
                // do the substitution
                dump(">>> subst %s with %s (new: %s)", t.underlying, subst.smap, newTargs)
                named.underlying = subst.typOrNil(t.underlying)
-               named.orig = named.underlying // for cycle detection (Checker.validType)
+               named.fromRHS = named.underlying // for cycle detection (Checker.validType)
 
                return named
 
index 2ea4d76d8b42494838b8f7e698f1d37e2fae2290..55b5c81540508671e7725a873d5f3f1d7501d145 100644 (file)
@@ -642,12 +642,15 @@ func (c *Chan) Dir() ChanDir { return c.dir }
 // Elem returns the element type of channel c.
 func (c *Chan) Elem() Type { return c.elem }
 
+// TODO(rfindley) Clean up Named struct below; specifically the fromRHS field (can we use underlying?).
+
 // A Named represents a named (defined) type.
 type Named struct {
        check      *Checker    // for Named.under implementation; nilled once under has been called
        info       typeInfo    // for cycle detection
        obj        *TypeName   // corresponding declared object
-       orig       Type        // type (on RHS of declaration) this *Named type is derived of (for cycle reporting)
+       orig       *Named      // original, uninstantiated type
+       fromRHS    Type        // type (on RHS of declaration) this *Named type is derived of (for cycle reporting)
        underlying Type        // possibly a *Named during setup; never a *Named once set up completely
        tparams    []*TypeName // type parameters, or nil
        targs      []Type      // type arguments (after instantiation), or nil
@@ -661,11 +664,14 @@ func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
        if _, ok := underlying.(*Named); ok {
                panic("types.NewNamed: underlying type must not be *Named")
        }
-       return (*Checker)(nil).newNamed(obj, underlying, methods)
+       return (*Checker)(nil).newNamed(obj, nil, underlying, nil, methods)
 }
 
-func (check *Checker) newNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
-       typ := &Named{check: check, obj: obj, orig: underlying, underlying: underlying, methods: methods}
+func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, tparams []*TypeName, methods []*Func) *Named {
+       typ := &Named{check: check, obj: obj, orig: orig, fromRHS: underlying, underlying: underlying, tparams: tparams, methods: methods}
+       if typ.orig == nil {
+               typ.orig = typ
+       }
        if obj.typ == nil {
                obj.typ = typ
        }
@@ -692,6 +698,10 @@ func (check *Checker) newNamed(obj *TypeName, underlying Type, methods []*Func)
 // Obj returns the type name for the named type t.
 func (t *Named) Obj() *TypeName { return t.obj }
 
+// _Orig returns the original generic type an instantiated type is derived from.
+// If t is not an instantiated type, the result is t.
+func (t *Named) _Orig() *Named { return t.orig }
+
 // TODO(gri) Come up with a better representation and API to distinguish
 //           between parameterized instantiated and non-instantiated types.
 
@@ -699,10 +709,13 @@ func (t *Named) Obj() *TypeName { return t.obj }
 // The result is non-nil for an (originally) parameterized type even if it is instantiated.
 func (t *Named) _TParams() []*TypeName { return t.tparams }
 
+// _SetTParams sets the type parameters of the named type t.
+func (t *Named) _SetTParams(tparams []*TypeName) { t.tparams = tparams }
+
 // _TArgs returns the type arguments after instantiation of the named type t, or nil if not instantiated.
 func (t *Named) _TArgs() []Type { return t.targs }
 
-// _SetTArgs sets the type arguments of Named.
+// SetTArgs sets the type arguments of the named type t.
 func (t *Named) _SetTArgs(args []Type) { t.targs = args }
 
 // NumMethods returns the number of explicit methods whose receiver is named type t.
@@ -741,9 +754,9 @@ func nextID() uint64 { return uint64(atomic.AddUint32(&lastID, 1)) }
 // A _TypeParam represents a type parameter type.
 type _TypeParam struct {
        check *Checker  // for lazy type bound completion
-       id    uint64    // unique id
+       id    uint64    // unique id, for debugging only
        obj   *TypeName // corresponding type name
-       index int       // parameter index
+       index int       // type parameter index in source order, starting at 0
        bound Type      // *Named or *Interface; underlying type is always *Interface
 }