aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/decl.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-05-26 21:42:09 -0700
committerRobert Griesemer <gri@golang.org>2021-05-27 17:51:15 +0000
commit8c99e5db431c28ef563fc4980b05b26f82172864 (patch)
tree480c65e8cd68a9a62c4d6b4f80b597bff104f0db /src/cmd/compile/internal/types2/decl.go
parent963f33b03b88e2c010d6a9876c3f0cc8d1f36f2d (diff)
downloadgo-8c99e5db431c28ef563fc4980b05b26f82172864.tar.gz
go-8c99e5db431c28ef563fc4980b05b26f82172864.zip
[dev.typeparams] cmd/compile/internal/types2: ensure that Named.check is nilled out once it is expanded
This is a port of - https://golang.org/cl/318849 - https://golang.org/cl/322974 For #45580. Change-Id: Ie0700ed6c8d472305d5ba7ff97da1ae063152aa3 Reviewed-on: https://go-review.googlesource.com/c/go/+/323030 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/decl.go')
-rw-r--r--src/cmd/compile/internal/types2/decl.go51
1 files changed, 39 insertions, 12 deletions
diff --git a/src/cmd/compile/internal/types2/decl.go b/src/cmd/compile/internal/types2/decl.go
index 1333e4c0ec..aa70f3880b 100644
--- a/src/cmd/compile/internal/types2/decl.go
+++ b/src/cmd/compile/internal/types2/decl.go
@@ -523,15 +523,37 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init syntax.Expr) {
// n0.check != nil, the cycle is reported.
func (n0 *Named) under() Type {
u := n0.underlying
- if u == nil {
- return Typ[Invalid]
+
+ if u == Typ[Invalid] {
+ return u
}
// If the underlying type of a defined type is not a defined
- // type, then that is the desired underlying type.
+ // (incl. instance) type, then that is the desired underlying
+ // type.
+ switch u.(type) {
+ case nil:
+ return Typ[Invalid]
+ default:
+ // common case
+ return u
+ case *Named, *instance:
+ // handled below
+ }
+
+ if n0.check == nil {
+ panic("internal error: Named.check == nil but type is incomplete")
+ }
+
+ // Invariant: after this point n0 as well as any named types in its
+ // underlying chain should be set up when this function exits.
+ check := n0.check
+
+ // If we can't expand u at this point, it is invalid.
n := asNamed(u)
if n == nil {
- return u // common case
+ n0.underlying = Typ[Invalid]
+ return n0.underlying
}
// Otherwise, follow the forward chain.
@@ -543,7 +565,16 @@ func (n0 *Named) under() Type {
u = Typ[Invalid]
break
}
- n1 := asNamed(u)
+ var n1 *Named
+ switch u1 := u.(type) {
+ case *Named:
+ n1 = u1
+ case *instance:
+ n1, _ = u1.expand().(*Named)
+ if n1 == nil {
+ u = Typ[Invalid]
+ }
+ }
if n1 == nil {
break // end of chain
}
@@ -554,11 +585,7 @@ func (n0 *Named) under() Type {
if i, ok := seen[n]; ok {
// cycle
- // TODO(gri) revert this to a method on Checker. Having a possibly
- // nil Checker on Named and TypeParam is too subtle.
- if n0.check != nil {
- n0.check.cycleError(path[i:])
- }
+ check.cycleError(path[i:])
u = Typ[Invalid]
break
}
@@ -568,8 +595,8 @@ func (n0 *Named) under() Type {
// We should never have to update the underlying type of an imported type;
// those underlying types should have been resolved during the import.
// Also, doing so would lead to a race condition (was issue #31749).
- // Do this check always, not just in debug more (it's cheap).
- if n0.check != nil && n.obj.pkg != n0.check.pkg {
+ // Do this check always, not just in debug mode (it's cheap).
+ if n.obj.pkg != check.pkg {
panic("internal error: imported type with unresolved underlying type")
}
n.underlying = u