aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/named.go
diff options
context:
space:
mode:
authorRob Findley <rfindley@google.com>2021-07-21 12:12:22 -0400
committerRobert Findley <rfindley@google.com>2021-07-28 19:15:09 +0000
commit473e493d18c277d69e40a4930af045d474ff2be4 (patch)
tree38f5d91931d924e17229c82d4152d61dc5b292a4 /src/cmd/compile/internal/types2/named.go
parente00a6ec084605b773cdb87971de5b5536c0cc13e (diff)
downloadgo-473e493d18c277d69e40a4930af045d474ff2be4.tar.gz
go-473e493d18c277d69e40a4930af045d474ff2be4.zip
[dev.typeparams] cmd/compile/internal/types2: merge instance and Named to eliminate sanitization
This is a port of CL 335929 to types2. It differs significantly from that CL to handle lazy loading, which wasn't tested in go/types. Additionally, the *Checker field was moved out of instance and back onto Named. This way we can tell whether a Named type is uninstantiated simply by checking whether Named.instance is non-nil, which simplified the code considerably. Fixes #46151 Change-Id: I617263bcfaa768ac5442213cecad8d567c2749fc Reviewed-on: https://go-review.googlesource.com/c/go/+/336252 Trust: Robert Findley <rfindley@google.com> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/types2/named.go')
-rw-r--r--src/cmd/compile/internal/types2/named.go45
1 files changed, 29 insertions, 16 deletions
diff --git a/src/cmd/compile/internal/types2/named.go b/src/cmd/compile/internal/types2/named.go
index da098b58b7..a88aeb0077 100644
--- a/src/cmd/compile/internal/types2/named.go
+++ b/src/cmd/compile/internal/types2/named.go
@@ -10,12 +10,13 @@ import "sync"
// A Named represents a named (defined) type.
type Named struct {
- check *Checker // for Named.under implementation; nilled once under has been called
+ check *Checker
info typeInfo // for cycle detection
obj *TypeName // corresponding declared object
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
+ instance *instance // position information for lazy instantiation, or nil
tparams []*TypeName // type parameters, or nil
targs []Type // type arguments (after instantiation), or nil
methods []*Func // methods declared for this type (not the method set of this type); signatures are type-checked lazily
@@ -34,7 +35,19 @@ func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
return (*Checker)(nil).newNamed(obj, nil, underlying, nil, methods)
}
-func (t *Named) expand() *Named {
+func (t *Named) load() *Named {
+ // If t is an instantiated type, it derives its methods and tparams from its
+ // base type. Since we expect type parameters and methods to be set after a
+ // call to load, we must load the base and copy here.
+ //
+ // underlying is set when t is expanded.
+ //
+ // By convention, a type instance is loaded iff its tparams are set.
+ if len(t.targs) > 0 && t.tparams == nil {
+ t.orig.load()
+ t.tparams = t.orig.tparams
+ t.methods = t.orig.methods
+ }
if t.resolve == nil {
return t
}
@@ -83,7 +96,7 @@ func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, tpar
if check != nil {
check.later(func() {
switch typ.under().(type) {
- case *Named, *instance:
+ case *Named:
panic("internal error: unexpanded underlying type")
}
typ.check = nil
@@ -104,10 +117,12 @@ func (t *Named) Orig() *Named { return t.orig }
// TParams returns the type parameters of the named type t, or nil.
// The result is non-nil for an (originally) parameterized type even if it is instantiated.
-func (t *Named) TParams() []*TypeName { return t.expand().tparams }
+func (t *Named) TParams() []*TypeName {
+ return t.load().tparams
+}
// SetTParams sets the type parameters of the named type t.
-func (t *Named) SetTParams(tparams []*TypeName) { t.expand().tparams = tparams }
+func (t *Named) SetTParams(tparams []*TypeName) { t.load().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 }
@@ -116,10 +131,10 @@ func (t *Named) TArgs() []Type { return t.targs }
func (t *Named) SetTArgs(args []Type) { t.targs = args }
// NumMethods returns the number of explicit methods whose receiver is named type t.
-func (t *Named) NumMethods() int { return len(t.expand().methods) }
+func (t *Named) NumMethods() int { return len(t.load().methods) }
// Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
-func (t *Named) Method(i int) *Func { return t.expand().methods[i] }
+func (t *Named) Method(i int) *Func { return t.load().methods[i] }
// SetUnderlying sets the underlying type and marks t as complete.
func (t *Named) SetUnderlying(underlying Type) {
@@ -129,18 +144,18 @@ func (t *Named) SetUnderlying(underlying Type) {
if _, ok := underlying.(*Named); ok {
panic("types2.Named.SetUnderlying: underlying type must not be *Named")
}
- t.expand().underlying = underlying
+ t.load().underlying = underlying
}
// AddMethod adds method m unless it is already in the method list.
func (t *Named) AddMethod(m *Func) {
- t.expand()
+ t.load()
if i, _ := lookupMethod(t.methods, m.pkg, m.name); i < 0 {
t.methods = append(t.methods, m)
}
}
-func (t *Named) Underlying() Type { return t.expand().underlying }
+func (t *Named) Underlying() Type { return t.load().underlying }
func (t *Named) String() string { return TypeString(t, nil) }
// ----------------------------------------------------------------------------
@@ -153,6 +168,8 @@ func (t *Named) String() string { return TypeString(t, nil) }
// is detected, the result is Typ[Invalid]. If a cycle is detected and
// n0.check != nil, the cycle is reported.
func (n0 *Named) under() Type {
+ n0.expand()
+
u := n0.Underlying()
if u == Typ[Invalid] {
@@ -168,7 +185,7 @@ func (n0 *Named) under() Type {
default:
// common case
return u
- case *Named, *instance:
+ case *Named:
// handled below
}
@@ -199,12 +216,8 @@ func (n0 *Named) under() Type {
var n1 *Named
switch u1 := u.(type) {
case *Named:
+ u1.expand()
n1 = u1
- case *instance:
- n1, _ = u1.expand().(*Named)
- if n1 == nil {
- u = Typ[Invalid]
- }
}
if n1 == nil {
break // end of chain