]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: add Named.SetTParams and Named.Orig methods
authorRobert Griesemer <gri@golang.org>
Wed, 14 Apr 2021 00:48:45 +0000 (17:48 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 14 Apr 2021 19:35:43 +0000 (19:35 +0000)
Named.SetTParams sets the type parameters for a named type.

Named.Orig returns the original generic type an instantiated
type is derived from. Added a new field orig for that purpose
and renamed the already existing orig field to fromRHS.

Finally, updated various comments.

Change-Id: Ic9d173e42740422d195713d8bdc62a54dc8c5f54
Reviewed-on: https://go-review.googlesource.com/c/go/+/309832
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/issues_test.go
src/cmd/compile/internal/types2/sanitize.go
src/cmd/compile/internal/types2/stdlib_test.go
src/cmd/compile/internal/types2/subst.go
src/cmd/compile/internal/types2/type.go
src/cmd/compile/internal/types2/typexpr.go

index f8559a43bbad295ae3af737fe38475a9e07a1b29..178bebe2ecad0cb7b9ec6b0d287f7b21a31c8705 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 {
@@ -611,9 +611,8 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
        } else {
                // defined type declaration
 
-               named := &Named{check: check, obj: obj}
+               named := check.newNamed(obj, nil, nil, nil, nil)
                def.setUnderlying(named)
-               obj.typ = named // make sure recursive type declarations terminate
 
                if tdecl.TParamList != nil {
                        check.openScope(tdecl, "type parameters")
@@ -622,7 +621,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, 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:
@@ -637,7 +636,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, 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 e1f5c92fc47aabc5efec5da8cc2f0bffe164613e..643d6789b513eea1a2527a7064f47c90973b3032 100644 (file)
@@ -195,7 +195,7 @@ L7 uses var z int`
        }
 }
 
-// This tests that the package associated with the types.Object.Pkg method
+// This tests that the package associated with the types2.Object.Pkg method
 // is the type's package independent of the order in which the imports are
 // listed in the sources src1, src2 below.
 // The actual issue is in go/internal/gcimporter which has a corresponding
index cd1719c8c0f915d6b91d426121810b286addd88b..8b8bc72d85dd26b86372f94ff595dc1af5b22f6c 100644 (file)
@@ -126,8 +126,8 @@ func (s sanitizer) typ(typ Type) Type {
                }
 
        case *Named:
-               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 6853bd23b0093bd7881e3525eb7a053f301d6992..c04f5e1c46d6b8ec124d9738e0a4fed93297a6d3 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// This file tests types.Check by using it to
+// This file tests types2.Check by using it to
 // typecheck the standard library and tests.
 
 package types2_test
index d730642831cff172fd66fc44dc27aa055f2147c6..d089317f7d5f3e7d21ccac33acf842d402119131 100644 (file)
@@ -385,8 +385,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 = new_targs
                subst.check.typMap[h] = named
                subst.cache[t] = named
@@ -394,7 +393,7 @@ func (subst *subster) typ(typ Type) Type {
                // do the substitution
                dump(">>> subst %s with %s (new: %s)", t.underlying, subst.smap, new_targs)
                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 daa00ddd3ae0317be913e276d35011d22c1419ab..e6c260ff6790c6663438ad62ce3e21b232712a1a 100644 (file)
@@ -224,10 +224,10 @@ func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
        if variadic {
                n := params.Len()
                if n == 0 {
-                       panic("types.NewSignature: variadic function must have at least one parameter")
+                       panic("types2.NewSignature: variadic function must have at least one parameter")
                }
                if _, ok := params.At(n - 1).typ.(*Slice); !ok {
-                       panic("types.NewSignature: variadic parameter must be of unnamed slice type")
+                       panic("types2.NewSignature: variadic parameter must be of unnamed slice type")
                }
        }
        return &Signature{recv: recv, params: params, results: results, variadic: variadic}
@@ -645,12 +645,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(gri) 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
        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 from (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
@@ -662,17 +665,17 @@ type Named struct {
 // The underlying type must not be a *Named.
 func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
        if _, ok := underlying.(*Named); ok {
-               panic("types.NewNamed: underlying type must not be *Named")
-       }
-       typ := &Named{obj: obj, orig: underlying, underlying: underlying, methods: methods}
-       if obj.typ == nil {
-               obj.typ = typ
+               panic("types2.NewNamed: underlying type must not be *Named")
        }
-       return typ
+       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}
+// newNamed is like NewNamed but with a *Checker receiver and additional orig argument.
+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
        }
@@ -682,6 +685,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.
 
@@ -689,10 +696,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.
@@ -704,10 +714,10 @@ func (t *Named) Method(i int) *Func { return t.methods[i] }
 // SetUnderlying sets the underlying type and marks t as complete.
 func (t *Named) SetUnderlying(underlying Type) {
        if underlying == nil {
-               panic("types.Named.SetUnderlying: underlying type must not be nil")
+               panic("types2.Named.SetUnderlying: underlying type must not be nil")
        }
        if _, ok := underlying.(*Named); ok {
-               panic("types.Named.SetUnderlying: underlying type must not be *Named")
+               panic("types2.Named.SetUnderlying: underlying type must not be *Named")
        }
        t.underlying = underlying
 }
@@ -731,9 +741,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
 }
 
index e7d24949a47981dec77c95c3caa1dc11390ed6c8..61b290c075109057cd93cdcdf9104dd0806a6e2f 100644 (file)
@@ -431,9 +431,9 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
 }
 
 // goTypeName returns the Go type name for typ and
-// removes any occurrences of "types." from that name.
+// removes any occurrences of "types2." from that name.
 func goTypeName(typ Type) string {
-       return strings.Replace(fmt.Sprintf("%T", typ), "types.", "", -1) // strings.ReplaceAll is not available in Go 1.4
+       return strings.Replace(fmt.Sprintf("%T", typ), "types2.", "", -1) // strings.ReplaceAll is not available in Go 1.4
 }
 
 // typInternal drives type checking of types.