diff --git a/src/cmd/compile/internal/types2/named.go b/src/cmd/compile/internal/types2/named.go index 11d7ba1734e..e451defce6d 100644 --- a/src/cmd/compile/internal/types2/named.go +++ b/src/cmd/compile/internal/types2/named.go @@ -562,6 +562,16 @@ func (t *Named) methodIndex(name string, foldCase bool) int { return -1 } +// rhs returns [Named.fromRHS]. +// +// In debug mode, it also asserts that n is in an appropriate state. +func (n *Named) rhs() Type { + if debug { + assert(n.stateHas(lazyLoaded | unpacked)) + } + return n.fromRHS +} + // Underlying returns the [underlying type] of the named type t, resolving all // forwarding declarations. Underlying types are never Named, TypeParam, or // Alias types. @@ -573,7 +583,7 @@ func (n *Named) Underlying() Type { // The gccimporter depends on writing a nil underlying via NewNamed and // immediately reading it back. Rather than putting that in Named.under // and complicating things there, we just check for that special case here. - if n.fromRHS == nil { + if n.rhs() == nil { assert(n.allowNilRHS) if n.allowNilUnderlying { return nil @@ -649,8 +659,8 @@ func (n *Named) resolveUnderlying() { t.mu.Lock() defer t.mu.Unlock() - assert(t.fromRHS != nil || t.allowNilRHS) - rhs = t.fromRHS + assert(t.rhs() != nil || t.allowNilRHS) + rhs = t.rhs() default: u = rhs // any type literal works @@ -735,7 +745,7 @@ func (n *Named) expandRHS() (rhs Type) { } assert(!n.stateHas(unpacked)) - assert(n.inst.orig.stateHas(unpacked | lazyLoaded)) + assert(n.inst.orig.stateHas(lazyLoaded | unpacked)) if n.inst.ctxt == nil { n.inst.ctxt = NewContext() @@ -760,7 +770,7 @@ func (n *Named) expandRHS() (rhs Type) { ctxt = check.context() } - rhs = check.subst(n.obj.pos, orig.fromRHS, m, n, ctxt) + rhs = check.subst(n.obj.pos, orig.rhs(), m, n, ctxt) // TODO(markfreeman): Can we handle this in substitution? // If the RHS is an interface, we must set the receiver of interface methods @@ -769,7 +779,7 @@ func (n *Named) expandRHS() (rhs Type) { if methods, copied := replaceRecvType(iface.methods, orig, n); copied { // If the RHS doesn't use type parameters, it may not have been // substituted; we need to craft a new interface first. - if iface == orig.fromRHS { + if iface == orig.rhs() { assert(iface.complete) // otherwise we are copying incomplete data crafted := check.newInterface() diff --git a/src/cmd/compile/internal/types2/validtype.go b/src/cmd/compile/internal/types2/validtype.go index c21c36d6f6f..bec6412f861 100644 --- a/src/cmd/compile/internal/types2/validtype.go +++ b/src/cmd/compile/internal/types2/validtype.go @@ -141,7 +141,8 @@ func (check *Checker) validType0(pos syntax.Pos, typ Type, nest, path []*Named) // Every type added to nest is also added to path; thus every type that is in nest // must also be in path (invariant). But not every type in path is in nest, since // nest may be pruned (see below, *TypeParam case). - if !check.validType0(pos, t.Origin().fromRHS, append(nest, t), append(path, t)) { + t.Origin().unpack() + if !check.validType0(pos, t.Origin().rhs(), append(nest, t), append(path, t)) { return false } diff --git a/src/go/types/named.go b/src/go/types/named.go index 564c1be3e0e..e49bdc96666 100644 --- a/src/go/types/named.go +++ b/src/go/types/named.go @@ -565,6 +565,16 @@ func (t *Named) methodIndex(name string, foldCase bool) int { return -1 } +// rhs returns [Named.fromRHS]. +// +// In debug mode, it also asserts that n is in an appropriate state. +func (n *Named) rhs() Type { + if debug { + assert(n.stateHas(lazyLoaded | unpacked)) + } + return n.fromRHS +} + // Underlying returns the [underlying type] of the named type t, resolving all // forwarding declarations. Underlying types are never Named, TypeParam, or // Alias types. @@ -576,7 +586,7 @@ func (n *Named) Underlying() Type { // The gccimporter depends on writing a nil underlying via NewNamed and // immediately reading it back. Rather than putting that in Named.under // and complicating things there, we just check for that special case here. - if n.fromRHS == nil { + if n.rhs() == nil { assert(n.allowNilRHS) if n.allowNilUnderlying { return nil @@ -652,8 +662,8 @@ func (n *Named) resolveUnderlying() { t.mu.Lock() defer t.mu.Unlock() - assert(t.fromRHS != nil || t.allowNilRHS) - rhs = t.fromRHS + assert(t.rhs() != nil || t.allowNilRHS) + rhs = t.rhs() default: u = rhs // any type literal works @@ -738,7 +748,7 @@ func (n *Named) expandRHS() (rhs Type) { } assert(!n.stateHas(unpacked)) - assert(n.inst.orig.stateHas(unpacked | lazyLoaded)) + assert(n.inst.orig.stateHas(lazyLoaded | unpacked)) if n.inst.ctxt == nil { n.inst.ctxt = NewContext() @@ -763,7 +773,7 @@ func (n *Named) expandRHS() (rhs Type) { ctxt = check.context() } - rhs = check.subst(n.obj.pos, orig.fromRHS, m, n, ctxt) + rhs = check.subst(n.obj.pos, orig.rhs(), m, n, ctxt) // TODO(markfreeman): Can we handle this in substitution? // If the RHS is an interface, we must set the receiver of interface methods @@ -772,7 +782,7 @@ func (n *Named) expandRHS() (rhs Type) { if methods, copied := replaceRecvType(iface.methods, orig, n); copied { // If the RHS doesn't use type parameters, it may not have been // substituted; we need to craft a new interface first. - if iface == orig.fromRHS { + if iface == orig.rhs() { assert(iface.complete) // otherwise we are copying incomplete data crafted := check.newInterface() diff --git a/src/go/types/validtype.go b/src/go/types/validtype.go index 46c7fae14fc..c23316da82f 100644 --- a/src/go/types/validtype.go +++ b/src/go/types/validtype.go @@ -144,7 +144,8 @@ func (check *Checker) validType0(pos token.Pos, typ Type, nest, path []*Named) b // Every type added to nest is also added to path; thus every type that is in nest // must also be in path (invariant). But not every type in path is in nest, since // nest may be pruned (see below, *TypeParam case). - if !check.validType0(pos, t.Origin().fromRHS, append(nest, t), append(path, t)) { + t.Origin().unpack() + if !check.validType0(pos, t.Origin().rhs(), append(nest, t), append(path, t)) { return false }