aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMark Freeman <mark@golang.org>2025-10-23 12:15:21 -0400
committerGopher Robot <gobot@golang.org>2025-10-27 11:47:38 -0700
commitd8a32f3d4b093d6a0d2235bf729bbef1d0b489d2 (patch)
tree1333c3c50aad0d464c29abba2769c919fd115661 /src
parentb2af92270f5e19c759b94912470a32b5e44a5b2e (diff)
downloadgo-d8a32f3d4b093d6a0d2235bf729bbef1d0b489d2.tar.xz
go/types, types2: wrap Named.fromRHS into Named.rhs
In debug mode, the Named.rhs method asserts that Named is in a state with Named.fromRHS populated. This caught a missing call to Named.unpack in validtype, which has been added. Change-Id: Id3f95f78f03d98a6efe87af6ac24f2ac2e285f96 Reviewed-on: https://go-review.googlesource.com/c/go/+/714242 Auto-Submit: Mark Freeman <markfreeman@google.com> Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/types2/named.go22
-rw-r--r--src/cmd/compile/internal/types2/validtype.go3
-rw-r--r--src/go/types/named.go22
-rw-r--r--src/go/types/validtype.go3
4 files changed, 36 insertions, 14 deletions
diff --git a/src/cmd/compile/internal/types2/named.go b/src/cmd/compile/internal/types2/named.go
index 11d7ba1734..e451defce6 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 c21c36d6f6..bec6412f86 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 564c1be3e0..e49bdc9666 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 46c7fae14f..c23316da82 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
}