Skip to content

Commit 892cad7

Browse files
committed
cmd/compile/internal/types2: add Named.SetTParams and Named.Orig methods
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 <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent 283f9fd commit 892cad7

File tree

7 files changed

+38
-30
lines changed

7 files changed

+38
-30
lines changed

src/cmd/compile/internal/types2/decl.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
333333
switch t.info {
334334
case unknown:
335335
t.info = marked
336-
t.info = check.validType(t.orig, append(path, t.obj)) // only types of current package added to path
336+
t.info = check.validType(t.fromRHS, append(path, t.obj)) // only types of current package added to path
337337
case marked:
338338
// cycle detected
339339
for i, tn := range path {
@@ -611,9 +611,8 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
611611
} else {
612612
// defined type declaration
613613

614-
named := &Named{check: check, obj: obj}
614+
named := check.newNamed(obj, nil, nil, nil, nil)
615615
def.setUnderlying(named)
616-
obj.typ = named // make sure recursive type declarations terminate
617616

618617
if tdecl.TParamList != nil {
619618
check.openScope(tdecl, "type parameters")
@@ -622,7 +621,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
622621
}
623622

624623
// determine underlying type of named
625-
named.orig = check.definedType(tdecl.Type, named)
624+
named.fromRHS = check.definedType(tdecl.Type, named)
626625

627626
// The underlying type of named may be itself a named type that is
628627
// incomplete:
@@ -637,7 +636,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
637636
// and which has as its underlying type the named type B.
638637
// Determine the (final, unnamed) underlying type by resolving
639638
// any forward chain.
640-
// TODO(gri) Investigate if we can just use named.origin here
639+
// TODO(gri) Investigate if we can just use named.fromRHS here
641640
// and rely on lazy computation of the underlying type.
642641
named.underlying = under(named)
643642
}

src/cmd/compile/internal/types2/issues_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ L7 uses var z int`
195195
}
196196
}
197197

198-
// This tests that the package associated with the types.Object.Pkg method
198+
// This tests that the package associated with the types2.Object.Pkg method
199199
// is the type's package independent of the order in which the imports are
200200
// listed in the sources src1, src2 below.
201201
// The actual issue is in go/internal/gcimporter which has a corresponding

src/cmd/compile/internal/types2/sanitize.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ func (s sanitizer) typ(typ Type) Type {
126126
}
127127

128128
case *Named:
129-
if orig := s.typ(t.orig); orig != t.orig {
130-
t.orig = orig
129+
if orig := s.typ(t.fromRHS); orig != t.fromRHS {
130+
t.fromRHS = orig
131131
}
132132
if under := s.typ(t.underlying); under != t.underlying {
133133
t.underlying = under

src/cmd/compile/internal/types2/stdlib_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// This file tests types.Check by using it to
5+
// This file tests types2.Check by using it to
66
// typecheck the standard library and tests.
77

88
package types2_test

src/cmd/compile/internal/types2/subst.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,16 +385,15 @@ func (subst *subster) typ(typ Type) Type {
385385

386386
// create a new named type and populate caches to avoid endless recursion
387387
tname := NewTypeName(subst.pos, t.obj.pkg, t.obj.name, nil)
388-
named := subst.check.NewNamed(tname, t.underlying, t.methods) // method signatures are updated lazily
389-
named.tparams = t.tparams // new type is still parameterized
388+
named := subst.check.newNamed(tname, t, t.underlying, t.tparams, t.methods) // method signatures are updated lazily
390389
named.targs = new_targs
391390
subst.check.typMap[h] = named
392391
subst.cache[t] = named
393392

394393
// do the substitution
395394
dump(">>> subst %s with %s (new: %s)", t.underlying, subst.smap, new_targs)
396395
named.underlying = subst.typOrNil(t.underlying)
397-
named.orig = named.underlying // for cycle detection (Checker.validType)
396+
named.fromRHS = named.underlying // for cycle detection (Checker.validType)
398397

399398
return named
400399

src/cmd/compile/internal/types2/type.go

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,10 @@ func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
224224
if variadic {
225225
n := params.Len()
226226
if n == 0 {
227-
panic("types.NewSignature: variadic function must have at least one parameter")
227+
panic("types2.NewSignature: variadic function must have at least one parameter")
228228
}
229229
if _, ok := params.At(n - 1).typ.(*Slice); !ok {
230-
panic("types.NewSignature: variadic parameter must be of unnamed slice type")
230+
panic("types2.NewSignature: variadic parameter must be of unnamed slice type")
231231
}
232232
}
233233
return &Signature{recv: recv, params: params, results: results, variadic: variadic}
@@ -645,12 +645,15 @@ func (c *Chan) Dir() ChanDir { return c.dir }
645645
// Elem returns the element type of channel c.
646646
func (c *Chan) Elem() Type { return c.elem }
647647

648+
// TODO(gri) Clean up Named struct below; specifically the fromRHS field (can we use underlying?).
649+
648650
// A Named represents a named (defined) type.
649651
type Named struct {
650652
check *Checker // for Named.under implementation
651653
info typeInfo // for cycle detection
652654
obj *TypeName // corresponding declared object
653-
orig Type // type (on RHS of declaration) this *Named type is derived of (for cycle reporting)
655+
orig *Named // original, uninstantiated type
656+
fromRHS Type // type (on RHS of declaration) this *Named type is derived from (for cycle reporting)
654657
underlying Type // possibly a *Named during setup; never a *Named once set up completely
655658
tparams []*TypeName // type parameters, or nil
656659
targs []Type // type arguments (after instantiation), or nil
@@ -662,17 +665,17 @@ type Named struct {
662665
// The underlying type must not be a *Named.
663666
func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
664667
if _, ok := underlying.(*Named); ok {
665-
panic("types.NewNamed: underlying type must not be *Named")
666-
}
667-
typ := &Named{obj: obj, orig: underlying, underlying: underlying, methods: methods}
668-
if obj.typ == nil {
669-
obj.typ = typ
668+
panic("types2.NewNamed: underlying type must not be *Named")
670669
}
671-
return typ
670+
return (*Checker)(nil).newNamed(obj, nil, underlying, nil, methods)
672671
}
673672

674-
func (check *Checker) NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
675-
typ := &Named{check: check, obj: obj, orig: underlying, underlying: underlying, methods: methods}
673+
// newNamed is like NewNamed but with a *Checker receiver and additional orig argument.
674+
func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, tparams []*TypeName, methods []*Func) *Named {
675+
typ := &Named{check: check, obj: obj, orig: orig, fromRHS: underlying, underlying: underlying, tparams: tparams, methods: methods}
676+
if typ.orig == nil {
677+
typ.orig = typ
678+
}
676679
if obj.typ == nil {
677680
obj.typ = typ
678681
}
@@ -682,17 +685,24 @@ func (check *Checker) NewNamed(obj *TypeName, underlying Type, methods []*Func)
682685
// Obj returns the type name for the named type t.
683686
func (t *Named) Obj() *TypeName { return t.obj }
684687

688+
// Orig returns the original generic type an instantiated type is derived from.
689+
// If t is not an instantiated type, the result is t.
690+
func (t *Named) Orig() *Named { return t.orig }
691+
685692
// TODO(gri) Come up with a better representation and API to distinguish
686693
// between parameterized instantiated and non-instantiated types.
687694

688695
// TParams returns the type parameters of the named type t, or nil.
689696
// The result is non-nil for an (originally) parameterized type even if it is instantiated.
690697
func (t *Named) TParams() []*TypeName { return t.tparams }
691698

699+
// SetTParams sets the type parameters of the named type t.
700+
func (t *Named) SetTParams(tparams []*TypeName) { t.tparams = tparams }
701+
692702
// TArgs returns the type arguments after instantiation of the named type t, or nil if not instantiated.
693703
func (t *Named) TArgs() []Type { return t.targs }
694704

695-
// SetTArgs sets the type arguments of Named.
705+
// SetTArgs sets the type arguments of the named type t.
696706
func (t *Named) SetTArgs(args []Type) { t.targs = args }
697707

698708
// 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] }
704714
// SetUnderlying sets the underlying type and marks t as complete.
705715
func (t *Named) SetUnderlying(underlying Type) {
706716
if underlying == nil {
707-
panic("types.Named.SetUnderlying: underlying type must not be nil")
717+
panic("types2.Named.SetUnderlying: underlying type must not be nil")
708718
}
709719
if _, ok := underlying.(*Named); ok {
710-
panic("types.Named.SetUnderlying: underlying type must not be *Named")
720+
panic("types2.Named.SetUnderlying: underlying type must not be *Named")
711721
}
712722
t.underlying = underlying
713723
}
@@ -731,9 +741,9 @@ func nextId() uint64 { return uint64(atomic.AddUint32(&lastId, 1)) }
731741
// A TypeParam represents a type parameter type.
732742
type TypeParam struct {
733743
check *Checker // for lazy type bound completion
734-
id uint64 // unique id
744+
id uint64 // unique id, for debugging only
735745
obj *TypeName // corresponding type name
736-
index int // parameter index
746+
index int // type parameter index in source order, starting at 0
737747
bound Type // *Named or *Interface; underlying type is always *Interface
738748
}
739749

src/cmd/compile/internal/types2/typexpr.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,9 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
431431
}
432432

433433
// goTypeName returns the Go type name for typ and
434-
// removes any occurrences of "types." from that name.
434+
// removes any occurrences of "types2." from that name.
435435
func goTypeName(typ Type) string {
436-
return strings.Replace(fmt.Sprintf("%T", typ), "types.", "", -1) // strings.ReplaceAll is not available in Go 1.4
436+
return strings.Replace(fmt.Sprintf("%T", typ), "types2.", "", -1) // strings.ReplaceAll is not available in Go 1.4
437437
}
438438

439439
// typInternal drives type checking of types.

0 commit comments

Comments
 (0)